• jsp自定义通用分页标签(超详细)


    导语:

      签在我们数据量多的时候我们通常都会使用分页表格来显示数据,但分页着个内容有很多,每一个页面的分页表格都需要重新写,代码的重复率太高,所以我们采用标签来就简化我们的代码,今天我们就来自定义 我们自己的通用分页标

     步骤:

    1.写个类,里面放分页条的基本属性

    PageBean

    1. import java.util.Map;
    2. import javax.servlet.http.HttpServletRequest;
    3. import com.mysql.jdbc.StringUtils;
    4. public class PageBean {
    5. /**
    6. * 页码
    7. */
    8. private int page = 1;
    9. /**
    10. * 每页显示的记录数
    11. */
    12. private int rows = 10;
    13. /**
    14. * 总记录数
    15. */
    16. private int total = 0;
    17. /**
    18. * 是否分页
    19. */
    20. private boolean pagination = true;
    21. /**
    22. * 记录查询的url,以便于点击分页时再次使用
    23. */
    24. private String url;
    25. /**
    26. * 存放请求参数,用于生成隐藏域中的元素
    27. */
    28. private Map parameterMap;
    29. /**
    30. * 根据传入的Request初始化分页对象
    31. *
    32. * @param request
    33. */
    34. public void setRequest(HttpServletRequest request) {
    35. if (!StringUtils.isNullOrEmpty(request.getParameter("page"))) {
    36. this.page = Integer.valueOf(request.getParameter("page"));
    37. }
    38. if (!StringUtils.isNullOrEmpty(request.getParameter("rows"))) {
    39. this.rows = Integer.valueOf(request.getParameter("rows"));
    40. }
    41. if (!StringUtils.isNullOrEmpty(request.getParameter("pagination"))) {
    42. this.pagination = Boolean.valueOf(request.getParameter("pagination"));
    43. }
    44. // 通过键值对把所有的参数全部保存起来
    45. this.url = request.getRequestURI();
    46. this.parameterMap = request.getParameterMap();
    47. // 把this放到页面中去便于使用
    48. request.setAttribute("pageBean", this);
    49. }
    50. public int getPage() {
    51. return page;
    52. }
    53. public void setPage(int page) {
    54. this.page = page;
    55. }
    56. public int getRows() {
    57. return rows;
    58. }
    59. public void setRows(int rows) {
    60. this.rows = rows;
    61. }
    62. public int getTotal() {
    63. return total;
    64. }
    65. public void setTotal(int total) {
    66. this.total = total;
    67. }
    68. public boolean isPagination() {
    69. return pagination;
    70. }
    71. public void setPagination(boolean pagination) {
    72. this.pagination = pagination;
    73. }
    74. public String getUrl() {
    75. return url;
    76. }
    77. public void setUrl(String url) {
    78. this.url = url;
    79. }
    80. public Map getParameterMap() {
    81. return parameterMap;
    82. }
    83. public void setParameterMap(Map parameterMap) {
    84. this.parameterMap = parameterMap;
    85. }
    86. // 计算起始页码
    87. public int getStartIndex() {
    88. return (this.page - 1) * this.rows;
    89. }
    90. // 获取总页数
    91. public int getTotalPage() {
    92. if (this.getTotal() % this.rows == 0) {
    93. return this.getTotal() / this.rows;
    94. } else {
    95. return this.getTotal() / this.rows + 1;
    96. }
    97. }
    98. // 上一页
    99. public int getPreviousPage() {
    100. return this.page - 1 > 0 ? this.page - 1 : 1;
    101. }
    102. // 下一页
    103. public int getNextPage() {
    104. return this.page + 1 > getTotalPage() ? getTotalPage() : this.page + 1;
    105. }
    106. }

    2.写一个类,里面放数据库的查询方法,也就是dao层

    BaseDao 

    1. import java.sql.Connection;
    2. import java.sql.PreparedStatement;
    3. import java.sql.ResultSet;
    4. import java.sql.SQLException;
    5. import java.util.ArrayList;
    6. import java.util.List;
    7. public final class BaseDao {
    8. public BaseDao() {
    9. }
    10. // 回调函数
    11. public static interface ICovent {
    12. List convent(ResultSet rs) throws SQLException;
    13. }
    14. public static List query(String sql, Object[] params, PageBean pagebean, ICovent covent) {
    15. List students = new ArrayList();
    16. // 不变部分
    17. Connection con = null;
    18. PreparedStatement ps = null;
    19. ResultSet rs = null;
    20. if (pagebean == null || !pagebean.isPagination()) {
    21. try {
    22. con = DBUtil.getConection();
    23. ps = con.prepareStatement(sql);
    24. // 设置查询参数
    25. int i = 1;
    26. for (Object param : params) {
    27. ps.setObject(i, param);
    28. i++;
    29. }
    30. rs = ps.executeQuery();
    31. // 通过使用者调用回调函数,执行转换
    32. students = covent.convent(rs);
    33. } catch (SQLException e) {
    34. e.printStackTrace();
    35. } finally {
    36. DBUtil.closeDB(rs, ps, con);
    37. }
    38. } else {
    39. try {
    40. String countsql = "select count(*) from (" + sql + ") emp";
    41. con = DBUtil.getConection();
    42. ps = con.prepareStatement(countsql);
    43. // 设置查询参数
    44. int i = 1;
    45. for (Object param : params) {
    46. ps.setObject(i, param);
    47. i++;
    48. }
    49. rs = ps.executeQuery();
    50. if (rs.next()) {
    51. pagebean.setTotal(rs.getInt(1));
    52. }
    53. // 判断总记录数是否大于0,大于则有数据,然后查询当前记录数(分页数据)
    54. // 如果没有直接返回
    55. if (pagebean.getTotal() == 0) {
    56. return students;
    57. }
    58. String pagesql = sql + "limit " + pagebean.getStartIndex() + "," + pagebean.getRows();
    59. con = DBUtil.getConection();
    60. ps = con.prepareStatement(pagesql);
    61. // 设置查询参数
    62. int f = 1;
    63. for (Object param : params) {
    64. ps.setObject(f, param);
    65. f++;
    66. }
    67. rs = ps.executeQuery();
    68. //
    69. students = covent.convent(rs);
    70. } catch (Exception e) {
    71. e.printStackTrace();
    72. }
    73. }
    74. return students;
    75. }
    76. }

     3.编写PagingTag助手类

    1. import java.io.IOException;
    2. import java.util.Map;
    3. import javax.servlet.jsp.JspException;
    4. import javax.servlet.jsp.JspWriter;
    5. import javax.servlet.jsp.tagext.BodyTagSupport;
    6. import com.zking.mvc.util.PageBean;
    7. public class PagingTag extends BodyTagSupport {
    8. private PageBean pageBean;
    9. public PageBean getPageBean() {
    10. return pageBean;
    11. }
    12. public void setPageBean(PageBean pageBean) {
    13. this.pageBean = pageBean;
    14. }
    15. @Override
    16. public int doStartTag() throws JspException {
    17. JspWriter out = this.pageContext.getOut();
    18. try {
    19. out.print(buildHtml());
    20. return SKIP_BODY;
    21. } catch (IOException e) {
    22. throw new JspException("分页标签异常" + e);
    23. }
    24. }
    25. // 构建分页的面板内容
    26. private String buildHtml() {
    27. //构建分页页面元素
    28. String pagingTag="
      \r\n"
    29. + " 第"+pageBean.getPage()+"页   \r\n"
    30. + " 共"+pageBean.getTotal()+"条记录   
    31. + " href=\"javascript: goPage(1);\">首页   
    32. + " href=\"javascript: goPage("+pageBean.getPreviousPage()+");\">上一页   \r\n"
    33. + " 第
    34. + " onkeypress=\"goSpecifiedPage(event,this.value);\" />页
    35. + " href=\"javascript: goPage(document.getElementById('pagingPageNum').value)\">GO\r\n"
    36. + "
      ";
  • String ycform="
    "
  • + "";
  • Map parameterMap = pageBean.getParameterMap();
  • for (Map.Entry param : parameterMap.entrySet()) {
  • String pageName=param.getKey();
  • if("page".equals(pageName)) continue;
  • String[] values = param.getValue();
  • for(String val: values) {
  • ycform += "";
  • }
  • }
  • ycform += "";
  • String script="";
  • return pagingTag+ycform+script;
  • }
  • }
  •  4.准备一个服务,servlet

     准备一个servlet用于处理请求,获取数据库中的数据,并转发到结果显示页面。

    1. package com.zking.mvc.dao;
    2. import java.io.IOException;
    3. import java.util.List;
    4. import javax.servlet.ServletException;
    5. import javax.servlet.annotation.WebServlet;
    6. import javax.servlet.http.HttpServlet;
    7. import javax.servlet.http.HttpServletRequest;
    8. import javax.servlet.http.HttpServletResponse;
    9. import com.zking.mvc.dome.Student;
    10. import com.zking.mvc.util.PageBean;
    11. import com.zking.mvc.util.StudentDao;
    12. @WebServlet("/students")
    13. public class StudetnServlet extends HttpServlet {
    14. private StudentDao studao = new StudentDao();
    15. @Override
    16. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    17. doPost(req, resp);
    18. }
    19. @Override
    20. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    21. PageBean pagebean = new PageBean();
    22. pagebean.setRequest(req);
    23. String sname = req.getParameter("sname");
    24. List students = studao.getStudents02(sname, pagebean);
    25. req.setAttribute("students", students);
    26. req.getRequestDispatcher("/students.jsp").forward(req, resp);
    27. }
    28. }

     5.编写过滤器,解决中文乱码问题

    1. import java.io.IOException;
    2. import java.util.Iterator;
    3. import java.util.Map;
    4. import java.util.Set;
    5. import javax.servlet.Filter;
    6. import javax.servlet.FilterChain;
    7. import javax.servlet.FilterConfig;
    8. import javax.servlet.ServletException;
    9. import javax.servlet.ServletRequest;
    10. import javax.servlet.ServletResponse;
    11. import javax.servlet.http.HttpServletRequest;
    12. import javax.servlet.http.HttpServletResponse;
    13. public class EncodingFiter implements Filter {
    14. private String encoding = "UTF-8";// 默认字符集
    15. public EncodingFiter() {
    16. super();
    17. }
    18. public void destroy() {
    19. }
    20. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    21. throws IOException, ServletException {
    22. HttpServletRequest req = (HttpServletRequest) request;
    23. HttpServletResponse res = (HttpServletResponse) response;
    24. // 中文处理必须放到 chain.doFilter(request, response)方法前面
    25. res.setContentType("text/html;charset=" + this.encoding);
    26. if (req.getMethod().equalsIgnoreCase("post")) {
    27. req.setCharacterEncoding(this.encoding);
    28. } else {
    29. Map map = req.getParameterMap();// 保存所有参数名=参数值(数组)的Map集合
    30. Set set = map.keySet();// 取出所有参数名
    31. Iterator it = set.iterator();
    32. while (it.hasNext()) {
    33. String name = (String) it.next();
    34. String[] values = (String[]) map.get(name);// 取出参数值[注:参数值为一个数组]
    35. for (int i = 0; i < values.length; i++) {
    36. values[i] = new String(values[i].getBytes("ISO-8859-1"), this.encoding);
    37. }
    38. }
    39. }
    40. chain.doFilter(request, response);
    41. }
    42. public void init(FilterConfig filterConfig) throws ServletException {
    43. String s = filterConfig.getInitParameter("encoding");// 读取web.xml文件中配置的字符集
    44. if (null != s && !s.trim().equals("")) {
    45. this.encoding = s.trim();
    46. }
    47. }
    48. }

     配置过滤器,要将过滤器配置到第一个位置,避免获取数据加载方法后面才加载过滤器,就没用了,所以我们选择在xml文件中配置

     

    6.配置标签库分页标签 

     

     7.使用案例:

    我写的是以students学生来当实体的,所以在封装的时候是以学生一些属性啊等等命名的 ,你可以自己看自己来就是。上面的servlet也是使用的学生来的,下面就让我们按学生来完成实例。

    dao层方法

    1. public List getStudents02(String sname, PageBean pagebean) {
    2. // 构造sql语句 变化部分
    3. String sql = "select * from Student t ";
    4. List prame = new ArrayList();
    5. if (!Objects.isNull(sname) && sname.length() > 0) {
    6. sql += " where t.sname like ?";
    7. prame.add(sname+"%");
    8. }
    9. List list = BaseDao.query(sql, prame.toArray(), pagebean, new ICovent() {
    10. public List convent(ResultSet rs) throws SQLException {
    11. List students = new ArrayList();
    12. while (rs.next()) {
    13. Student stu = new Student();
    14. stu.setSid(rs.getInt("sid"));
    15. stu.setSname(rs.getString("sname"));
    16. stu.setSex(rs.getString("sex"));
    17. stu.setSage(rs.getInt("sage"));
    18. stu.setSclass(rs.getString("sclass"));
    19. students.add(stu);
    20. }
    21. return students;
    22. }
    23. });
    24. return list;
    25. }
    26. 下面我们只需要在我们的页面引入我们的标签库就行了。 

       使用分页标签
      首先在页面中引入标签

      <%@taglib prefix="z" uri="/zking" %>
      

      将原来的分页功能,替换为标签即可

      <z:paging pageBean="${pageBean}"/>

       总结:

      通用分页需要的是通用,着需要将其进行一个差分封装,但在我们还不熟悉的时候我们在编写代码时应该先不考虑封装,先将分页写出来,然后提取公共构造,封装继承。通用分页步骤就是先分析分页条属性,然后封装属性实体,然后编写dao层方法提取公共部分,然后编写助手类,为了避免出现乱码问题,在编写一个字符过滤器,过滤所有请求,然后就开始配置过滤器,在xml中配置在第一位,然后在标签库描述文件中添加分页标签,然后就可以按自己需求来使用了。全球其实通用分页的思想就是将能提取的部分给提取出来然后拼接,辛苦现在,幸福以后。

       

    27. 相关阅读:
      编程入门之学哪种编程语言?
      EasyPoi导入校验+导入自定义查询等校验
      优雅停止 SpringBoot 服务,拒绝 kill -9 暴力停止
      js 闭包:概念-用途-弊端
      c语言:三个数排序(if-else实现)
      高效的工作学习方法
      冒泡事件在Vue中的应用
      学习笔记(13)ES6新特性
      腾讯发布财报,地主家也没有余粮了?
      【密码学】RSA的攻与防_2.0
    28. 原文地址:https://blog.csdn.net/weixin_67150631/article/details/125887595