自定义通用分页标签一行代码完成分页效果(内含源码)(下)

简介: 自定义通用分页标签一行代码完成分页效果(内含源码)(下)

三、自定义通用分页标签分析以及编写

分页分页,操作的就是页数,所以我们助手类的核心属性就是“页数、条目、总记录数等”,而这些刚好我又封装成了分页工具类,我们就可以将类作为类型定义变量,由于我们是没有主体内容但是要向页面输出内容,那么我们就可以拿到out对象进行页面显示,out对象里的内容就是拼接我们平常的“分页标签”。

然后我们将拼接内容中的可变参数,也就是操作上一页下一页或者点击页码进行跳转的代码,替换成我们早已在PageBean分页工作类写好的方法进行调用即可。

package com.xw.tag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.JspTag;
import com.xw.util.PageBean;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
/**自定义通用分页标签PageBean
 * @author Java方文山
 *
 */
public class PageBeanTag extends BodyTagSupport {
    private PageBean pageBean;
    public PageBean getPageBean() {
        return pageBean;
    }
    public void setPageBean(PageBean pageBean) {
        this.pageBean = pageBean;
    }
    @Override
    public int doStartTag() throws JspException {
        JspWriter out = pageContext.getOut();
        try {
            out.print(toHTML());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return SKIP_BODY;
    }
    private String toHTML() {
        StringBuilder sb = new StringBuilder();
//        这里拼接的是一个上一次发送的请求以及携带的参数,唯一改变的就是页码
        sb.append("<form id='pageBeanForm' action='"+pageBean.getUrl()+"' method='post'>");
        sb.append("<input type='hidden' name='page'>");
//        重要设置拼接操作,将上一次请求参数携带到下一次
        Map<String, String[]> paMap = pageBean.getParameterMap();
        if(paMap !=null && paMap.size()>0){
            Set<Map.Entry<String, String[]>> entrySet = paMap.entrySet();
            for (Map.Entry<String, String[]> entry : entrySet) {
                for (String val : entry.getValue()) {
                    if(!"page".equals(entry.getKey())){
                        sb.append("<input type='hidden' name='"+entry.getKey()+"' value='"+val+"'>");
                    }
                }
            }
        }
        sb.append("</form>");
        int page = pageBean.getPage();
        int max = pageBean.getMaxPage();
        int before = page > 4 ? 4 : page-1;
        int after = 10 - 1 - before;
        after = page+after > max ? max-page : after;
//        disabled
        boolean startFlag = page == 1;
        boolean endFlag = max == page;
//        拼接分页条
        sb.append("<ul class='pagination'>");
        sb.append("<li class='page-item "+(startFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage(1)'>首页</a></li>");
        sb.append("<li class='page-item "+(startFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage("+pageBean.getPrevPage()+")'>&lt;</a></li>");
//        代表了当前页的前4页
        for (int i = before; i > 0 ; i--) {
            sb.append("<li class='page-item'><a class='page-link' href='javascript:gotoPage("+(page-i)+")'>"+(page-i)+"</a></li>");
        }
        sb.append("<li class='page-item active'><a class='page-link' href='javascript:gotoPage("+pageBean.getPage()+")'>"+pageBean.getPage()+"</a></li>");
//        代表了当前页的后5页
        for (int i = 1; i <= after; i++) {
            sb.append("<li class='page-item'><a class='page-link' href='javascript:gotoPage("+(page+i)+")'>"+(page+i)+"</a></li>");
        }
        sb.append("<li class='page-item "+(endFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage("+pageBean.getNextPage()+")'>&gt;</a></li>");
        sb.append("<li class='page-item "+(endFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage("+pageBean.getMaxPage()+")'>尾页</a></li>");
        sb.append("<li class='page-item go-input'><b>到第</b><input class='page-link' type='text' id='skipPage' name='' /><b>页</b></li>");
        sb.append("<li class='page-item go'><a class='page-link' href='javascript:skipPage()'>确定</a></li>");
        sb.append("<li class='page-item'><b>共"+pageBean.getTotal()+"条数据</b>&nbsp;&nbsp;<b>共"+pageBean.getMaxPage()+"页数</b></li>");
        sb.append("</ul>");
//        拼接分页的js代码
        sb.append("<script type='text/javascript'>");
        sb.append("function gotoPage(page) {");
        sb.append("document.getElementById('pageBeanForm').page.value = page;");
        sb.append("document.getElementById('pageBeanForm').submit();");
        sb.append("}");
        sb.append("function skipPage() {");
        sb.append("var page = document.getElementById('skipPage').value;");
        sb.append("if (!page || isNaN(page) || parseInt(page) < 1 || parseInt(page) > "+max+") {");
        sb.append("alert('请输入1~N的数字');");
        sb.append("return;");
        sb.append("}");
        sb.append("gotoPage(page);");
        sb.append("}");
        sb.append("</script>");
        return sb.toString();
    }
}

tld文件的编写

<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
   "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- 标签库描述符 -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
  <tlib-version>1.0</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>Simple Tags</short-name>
  <uri>/xw</uri>
    <tag>
    <!-- 标签名 -->
    <name>PageBean</name>
    <!-- 标签助手类 -->
    <tag-class>com.xw.tag.PageBeanTag</tag-class>
    <!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 -->
    <body-content>jsp</body-content>
    <attribute>
      <!-- 属性名, PageBeanTag类中的PageBean属性相匹配 -->
      <name>pageBean</name>
      <!-- 表示该属性是否为必要的属性 -->
      <required>true</required>
      <!-- 该属性是否可以接受EL表示式的值 -->
      <rtexprvalue>true</rtexprvalue>
      <!-- 标签描述,用于说明标签的作用 -->
      <description>通用分页标签</description>
    </attribute>
    </tag>
</taglib>

注意:全路径名称一点不要错了,属性也必须和助手类一致。

五、案例实操

1.jsp页面的搭建

在完成以上操作后,我们就可以进行jsp页面搭建了,这里博主也为大家准备好啦!!

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib prefix="xw" uri="/xw" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link
  href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
  rel="stylesheet">
<script
  src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script>
<title>书籍列表</title>
<style type="text/css">
.page-item input {
  padding: 0;
  width: 40px;
  height: 100%;
  text-align: center;
  margin: 0 6px;
}
.page-item input, .page-item b {
  line-height: 38px;
  float: left;
  font-weight: 400;
}
.page-item.go-input {
  margin: 0 10px;
}
</style>
</head>
<body>
<!-- 如果没值先去拿数据 -->
<c:if test="${empty PageBeans }">
<jsp:forward page="/Book.do"></jsp:forward>
</c:if>
<center>
  <form class="form-inline"
    action="${pageContext.request.contextPath }/Book.do" method="post">
    <div class="form-group mb-2">
      <input type="text" class="" name="bname"
        placeholder="请输入书籍名称">
    </div>
    <button type="submit" class="btn btn-primary mb-2">查询</button>
  </form>
  <table class="table table-striped ">
    <thead>
      <tr>
        <th scope="col">书籍ID</th>
        <th scope="col">书籍名</th>
        <th scope="col">价格</th>
      </tr>
    </thead>
    <tbody>
      <c:if test="${not empty books }">
        <c:forEach items="${books }" var="b">
          <tr>
            <td>${b.bid }</td>
            <td>${b.bname }</td>
            <td>${b.price }</td>
          </tr>
        </c:forEach>
      </c:if>
    </tbody>
  </table>
  <xw:PageBean pageBean="${PageBeans }"></xw:PageBean>
  </center>
</body>
</html>

注意:引入我们的自己所编写的自定义标签<%@taglib prefix="xw" uri="/xw" %>

2.Servlet的编写

PageBean初始化的的request就是源于这个Servlet页面

package com.xw.servlet;
import java.io.IOException;
import java.util.List;
import java.util.Map;
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 javax.servlet.http.HttpSession;
import com.xw.dao.BookDao;
import com.xw.entity.Book;
import com.xw.util.PageBean;
import sun.net.www.content.text.plain;
/**
 * 处理book分页的servlet
 */
@WebServlet("/Book.do")
public class BookServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doPost(request, response);
  }
  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // 实例化dao层和分页工具类以及Book实体对象
    BookDao bookdao = new BookDao();
    PageBean PageBean = new PageBean();
    // 调用初始化数据的方法
    PageBean.setPagebean(request);
    Book book = new Book();
    // 将客户端的请求参数赋值给book实体
    book.setBname(request.getParameter("bname"));
    try {
      // 将结果保存到域对象
      // 调用bookdao
      List<Book> baseDaoTest = bookdao.BaseDaoTest(book, PageBean);
      request.setAttribute("books", baseDaoTest);
      request.setAttribute("PageBeans", PageBean);
      // 转发回显客户端
       request.getRequestDispatcher("Index.jsp").forward(request, response);
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

3.浏览器演示效果

是不是很简单呢? 跟我学Java我行你也行😎!!!

四、中文乱码问题

      这是博主在测试的时候发现的问题,乱码通常是因为文本使用了不正确的字符编码方式,导致无法正确显示字符也或是没有配置UTF-8字符编码问题。

       这里提供一个解决方案过滤器(Filter),过滤器是一种用于筛选、过滤或处理数据的工具或方法。它可以用于数据处理、图像处理、音频处理等领域。例如,在图像处理中,可以使用滤镜(filter)对图像进行增强或添加特效。简单来说就像是个筛子,将一些不满足条件的东西进行拦截以及“加工处理”,我们利用过滤器设置统一编码。

package com.xw.util;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 中文乱码处理
 * 
 */
@WebFilter("/*")
public class EncodingFiter implements Filter {
  private String encoding = "UTF-8";// 默认字符集
  public EncodingFiter() {
    super();
  }
  public void destroy() {
  }
  public void doFilter(ServletRequest request, ServletResponse response,
      FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    // 中文处理必须放到 chain.doFilter(request, response)方法前面
    res.setContentType("text/html;charset=" + this.encoding);
    if (req.getMethod().equalsIgnoreCase("post")) {
      req.setCharacterEncoding(this.encoding);
    } else {
      Map map = req.getParameterMap();// 保存所有参数名=参数值(数组)的Map集合
      Set set = map.keySet();// 取出所有参数名
      Iterator it = set.iterator();
      while (it.hasNext()) {
        String name = (String) it.next();
        String[] values = (String[]) map.get(name);// 取出参数值[注:参数值为一个数组]
        for (int i = 0; i < values.length; i++) {
          values[i] = new String(values[i].getBytes("ISO-8859-1"),
              this.encoding);
        }
      }
    }
    chain.doFilter(request, response);
  }
  public void init(FilterConfig filterConfig) throws ServletException {
    String s = filterConfig.getInitParameter("encoding");// 读取web.xml文件中配置的字符集
    if (null != s && !s.trim().equals("")) {
      this.encoding = s.trim();
    }
  }
}

以上就是自定义分页标签的全部内容了,感谢观看!!

相关文章
|
前端开发 Java 测试技术
通用分页【上】
JUnit是流行的、开源的Java单元测试框架,它提供了一种简单而强大的方式来测试Java应用程序中的单元代码。JUnit测试通常涉及创建和运行测试用例,而测试用例是一组独立的测试步骤,用于验证代码是否按照预期工作。JUnit测试通常分为以下四个步骤:定义测试用例:定义每个测试方法所需的输入参数以及期望的输出结果;编写测试代码:编写测试方法并使用断言(Assertion)来验证代码是否按照预期工作;运行测试用例:通常使用JUnit测试浏览器或者其他测试工具来运行测试用例;查看测试结果。
|
SQL 关系型数据库 MySQL
通用分页的详细讲解看这一篇就够了(内含源码)(上)
通用分页的详细讲解看这一篇就够了(内含源码)
119 0
|
16天前
|
SQL Java 数据库连接
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
MyBatis-Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。本文讲解了最新版MP的使用教程,包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段等核心功能。
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
|
5月前
|
前端开发 JavaScript 数据库
分页,快捷链接表单,分页表单,常用软件开发之分页,快捷链接分页表单添加显示,可以做的分页统计,一个简单的添加页面,数据条理清晰呈现如何设计,如何修改成自己想要的,要会编写接口文档,一边写接口
分页,快捷链接表单,分页表单,常用软件开发之分页,快捷链接分页表单添加显示,可以做的分页统计,一个简单的添加页面,数据条理清晰呈现如何设计,如何修改成自己想要的,要会编写接口文档,一边写接口
|
算法 JavaScript Java
通用分页【下】(将分页封装成标签)
调试()是指在软件开发过程中,通过识别、定位和解决程序错误或问题的过程。调试的目的是找出代码中的错误、异常或不正常的行为,并修复它们,以确保程序能够按照预期的方式运行。调试是一个重要的开发技巧,可以帮助开发人员理解程序的执行过程、找出错误的原因,并从中学习和改进。调试可以使用不同的工具和技术来辅助,例如打印输出、日志记录、调试器(debugger)等。调试是开发过程中不可或缺的一部分,可以帮助开发人员提高代码质量、加快解决问题的速度,并优化程序的性能和可靠性。
|
前端开发 数据管理 Java
通用分页(下)
通用分页(下)
43 0
|
监控 前端开发 算法
通用分页(前端)
通用分页(前端)
46 1
|
Java 数据库
通用分页之详解】
通用分页之详解】
40 1
|
7月前
|
前端开发 关系型数据库 MySQL
通用分页详解
通用分页详解
59 0
通用分页(后台分页)
通用分页(后台分页)
56 0