在jsp技术中,自定义标签是一个非常重要的知识点。很多人学完自定义标签后,在做项目时还是不知道在哪些地方可以用得上。其实我们在很多情况下可以用到,今天就给大家分享一个业务系统中高频使用到的一个功能“分页”。
分页看起来很简单,实际上,之中设计到的业务逻辑还是比较多的。
首先我们都知道,一个分页功能会包含当前页,总页数,总记录数,当前页记录集等等一些必要信息。那么在设计之初,我们把分页抽象为一个对象。
分页对象
package cn.gson.mvc.model;
import java.util.List;
/**
* 分页对象
* @author 夏悸
*
* @param <T>
*/
public class Pager<T> {
/**
* 当前页码
*/
private Integer page = 1;
/**
* 页大小
*/
private Integer pageSize = 10;
/**
* 当前页的数据
*/
private List<T> rows;
/**
* 总记录数
*/
private Long total;
/**
* 总页数
*/
private Integer totalPage;
public Pager(Integer page) {
this.page = page;
}
public Pager(Integer page, Integer pageSize) {
this.page = page;
this.pageSize = pageSize;
}
/**
* 获取分页参数
* @return
*/
public int getStart() {
return (this.page - 1) * this.pageSize;
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = Math.max(page, 1);
}
public List<T> getRows() {
return rows;
}
public void setRows(List<T> rows) {
this.rows = rows;
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
public Integer getTotalPage() {
return (int) Math.ceil(total / pageSize);
}
public void setTotalPage(Integer totalPage) {
this.totalPage = totalPage;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getPageSize() {
return pageSize;
}
}
自定义pager标签
要自定义jsp标签,我们需要些一个类SimpleTagSupport,然后在doTag方法中实现我们的分页逻辑
package cn.gson.mvc.tag;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import cn.gson.mvc.common.StringUtils;
import cn.gson.mvc.model.Pager;
/**
* 分页标签
*
* @author 夏悸
*
*/
public class PagerTag extends SimpleTagSupport {
private String url;
private Pager<?> pager;
@Override
public void doTag() throws JspException, IOException {
StringBuffer sb = new StringBuffer("<div class=\"page\">");
String queryStr = this.getParamStr();
if (pager.getPage() == 1) {
sb.append("<a class=\"disable\">首页</a>");
sb.append("<a class=\"disable\">上一页</a>");
} else {
sb.append("<a href=\"" + url + "?p=1" + queryStr + "\">首页</a>");
sb.append("<a href=\"" + url + "?p=" + (pager.getPage() - 1) + queryStr + "\">上一页</a>");
}
if (pager.getPage() == pager.getTotalPage()) {
sb.append("<a class=\"disable\">下一页</a>");
sb.append("<a class=\"disable\">尾页</a>");
} else {
sb.append("<a href=\"" + url + "?p=" + (pager.getPage() + 1) + queryStr + "\">下一页</a>");
sb.append("<a href=\"" + url + "?p=" + pager.getTotalPage() + queryStr + "\">尾页</a>");
}
sb.append(String.format("%s/%s(共有%s条)", pager.getPage(), pager.getTotalPage(), pager.getTotal()));
sb.append("</div>");
getJspContext().getOut().write(sb.toString());
}
public String getParamStr() throws UnsupportedEncodingException {
PageContext pageContext = (PageContext) this.getJspContext();
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
Enumeration<String> pnames = request.getParameterNames();
List<String> params = new ArrayList<>();
while (pnames.hasMoreElements()) {
String name = (String) pnames.nextElement();
if (!"p".equalsIgnoreCase(name)) {
String[] values = request.getParameterValues(name);
for (String value : values) {
if (!StringUtils.isEmpty(value)) {
params.add(name + "=" + URLEncoder.encode(value, "UTF-8"));
}
}
}
}
StringBuffer sb = new StringBuffer();
if (params.size() > 0) {
sb.append("&");
for (String item : params) {
sb.append(item).append("&");
}
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
public void setUrl(String url) {
this.url = url;
}
public void setPager(Pager<?> pager) {
this.pager = pager;
}
}
定义tld文件
<?xml version="1.0" encoding="utf-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>2.0</tlib-version>
<short-name>myTag</short-name>
<uri>http://www.gson.cn/tags</uri>
<tag>
<name>pager</name>
<tag-class>cn.gson.mvc.tag.PagerTag</tag-class>
<body-content>empty</body-content>
<attribute>
<description>分页请求</description>
<!-- 属性名称,必须要和类中定义的属性名一致 -->
<name>url</name>
<!-- 属性是否是必须的 -->
<required>true</required>
<!-- 属性值是否可以用表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<description>分页对象</description>
<name>pager</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
在jsp中使用自定义标签
1、首页在jsp头部通过jsp指定导入自定义一标签
<%@ taglib uri="http://www.gson.cn/tags" prefix="myTag"%>
2、调用标签
<myTag:pager pager="${pager }" url="user/list"/>
重点是上面的pager属性,怎么出来。
当我们发生请求到servlet中请求分页数据,在servlet中我们对数据分页所需要的用到的所有数据进行封装
servlet的处理
package cn.gson.mvc.controller.user;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.gson.mvc.model.Pager;
import cn.gson.mvc.model.bean.User;
import cn.gson.mvc.model.dao.UserDao;
@WebServlet("/user/list")
public class UserListController extends HttpServlet {
private static final long serialVersionUID = 1L;
private UserDao udao = new UserDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
String p = req.getParameter("p");
String userName = req.getParameter("userName");
String tel = req.getParameter("tel");
int page = 1;
if (p != null) {
page = Integer.parseInt(p);
}
Pager<User> pager = new Pager<>(page);
udao.findAll(pager, userName, tel);
req.setAttribute("pager", pager);
req.getRequestDispatcher("/WEB-INF/jsp/list.jsp").forward(req, resp);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
可以看到在servlet中我们创建了pager对象,并且把pager对象传入到了Dao中,所以我们dao中其实要做的事情就是去完善pager中除了page之外的其他属性,主要是rows和total。