详解通用分页(前端)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介: 详解通用分页(前端)

今日金句

古之立大事者,不惟有超世之才,亦必有坚忍不拔之志



前言

上一篇博客我们讲的是后端的通用分页,已经可以很大地减少代码量,那么在繁琐的前端代码中去用通用分页减少代码量效果就更不用多说了,其实我们只要在后端代码的基础上添加前端分页所需要用的功能即可完成。

一、 核心思想

此时我们演绎一下查询:

  • 第一次查询:在输入框输入“圣墟”点击查询,那么后台分页要拿到哪些参数呢 ?
  • 1.bname=圣墟 2.page=1 3.rows=10 4.pagination=true
  • 3和4可传可不传,但是不分页时4必须传递false
  • 第二次查询(下一页) :
  • 1.bname=圣墟 2.page=2 3.rows=10 4.pagination=true
  • 3和4可传可不传,但是不分页时4必须传递false
  • 相较于上一次请求,我们发现只是页码改变了
  • 第三次查询( 尾页)
  • 1.bname=圣墟 2.page=max 3.rows=10 4.pagination=true
  • 3和4可传可不传,但是不分页时4必须传递false
  • 相较于上一次请求,也只是页码改变了,其它查询条件都不变

通过以上演绎我们就能得出分页的核心思想:我们将大量的内容或数据分割成各个页面,查询时查询的条件只需要修改页码即可(有模糊查询加参数即可)

二、实例

2.1 连接数据库

package com.xqx.util;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**数据库帮助类
 * 提供了一组获得或关闭数据库对象的方法
 * @author W许潜行
 *
 */
public class DBHepler {
  private static String driver;
  private static String url;
  private static String user;
  private static String password;
  static {// 静态块执行一次,加载 驱动一次
    try {
      InputStream is = DBHepler.class.getResourceAsStream("config.properties");
      Properties properties = new Properties();
      properties.load(is);
      driver = properties.getProperty("driver");
      url = properties.getProperty("url");
      user = properties.getProperty("user");
      password = properties.getProperty("pwd");
      Class.forName(driver);
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }
  /**
   * 获得数据连接对象
   * 
   * @return
   */
  public static Connection getConnection() {
    try {
      Connection conn = DriverManager.getConnection(url, user, password);
      return conn;
    } catch (SQLException e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }
  public static void close(ResultSet rs) {
    if (null != rs) {
      try {
        rs.close();
      } catch (SQLException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
      }
    }
  }
  public static void close(Statement stmt) {
    if (null != stmt) {
      try {
        stmt.close();
      } catch (SQLException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
      }
    }
  }
  public static void close(Connection conn) {
    if (null != conn) {
      try {
        conn.close();
      } catch (SQLException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
      }
    }
  }
  public static void close(Connection conn, Statement stmt, ResultSet rs) {
    close(rs);
    close(stmt);
    close(conn);
  }
  public static boolean isOracle() {
    return "oracle.jdbc.driver.OracleDriver".equals(driver);
  }
  public static boolean isSQLServer() {
    return "com.microsoft.sqlserver.jdbc.SQLServerDriver".equals(driver);
  }
  public static boolean isMysql() {
    return "com.mysql.cj.jdbc.Driver".equals(driver);
  }
  public static void main(String[] args) {
    Connection conn = DBHepler.getConnection();
    System.out.println(conn);
    DBHepler.close(conn);
    System.out.println("isOracle:" + isOracle());
    System.out.println("isSQLServer:" + isSQLServer());
    System.out.println("isMysql:" + isMysql());
    System.out.println("数据库连接(关闭)成功");
  }
}

2.2 编写实体类以及dao方法

entity

package com.xqx.entity;
/**
 * 
 * @author W许潜行
 *
 */
public class Book {
  private int bid;
  private String bname;
  private float price;
  @Override
  public String toString() {
    return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
  }
  public int getBid() {
    return bid;
  }
  public void setBid(int bid) {
    this.bid = bid;
  }
  public String getBname() {
    return bname;
  }
  public void setBname(String bname) {
    this.bname = bname;
  }
  public float getPrice() {
    return price;
  }
  public void setPrice(float price) {
    this.price = price;
  }
  public Book(int bid, String bname, float price) {
    super();
    this.bid = bid;
    this.bname = bname;
    this.price = price;
  }
  public Book() {
    // TODO Auto-generated constructor stub
  }
}

非空判断类

package com.xqx.util;
/**
 * 封装非空判断方法
 * 
 * @author W许潜行
 *
 */
public class StringUtils {
  // 私有的构造方法,保护此类不能在外部实例化
  private StringUtils() {
  }
  /**
   * 如果字符串等于null或去空格后等于"",则返回true,否则返回false
   * 
   * @param s
   * @return
   */
  public static boolean isBlank(String s) {
    boolean b = false;
    if (null == s || s.trim().equals("")) {
      b = true;
    }
    return b;
  }
  /**
   * 
   * 如果字符串不等于null或去空格后不等于"",则返回true,否则返回false
   * 
   * @param s
   * @return
   */
  public static boolean isNotBlank(String s) {
    return !isBlank(s);
  }
}

Basedao

package com.xqx.dao;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.xqx.entity.Book;
import com.xqx.util.DBHepler;
import com.xqx.util.PageBean;
import com.xqx.util.StringUtils;
public class BaseDao<T> {
  /**
   * @param sql 语句
   * @param classes 类
   * @param pageBean
   * @return
   * @throws Exception
   */
  public List<T> query(String sql,Class<T> classes ,PageBean pageBean) throws Exception {
    List<T> list = new ArrayList<T>();
    // 建立连接
    Connection conn = DBHepler.getConnection();
    // 执行sql语句
    PreparedStatement ps = conn.prepareStatement(sql);
    // 结果集
    ResultSet rs = ps.executeQuery();
    while (rs.next()) {
      //类实例
      T t = classes.newInstance();
      //拿到所有属性
      Field[] fields = classes.getDeclaredFields();
      for (Field fieldName : fields) {
        //打开访问权限
        fieldName.setAccessible(true);
        //为t赋值
        fieldName.set(t, rs.getObject(fieldName.getName()));
      }
      list.add(t);
    }
    return list;
  }
  public List<T> query2(String sql,Class<T> classes ,PageBean pageBean) throws Exception {
    List<T> list = new ArrayList<T>();
    // 建立连接
    Connection conn = DBHepler.getConnection();
    // 执行sql语句
    PreparedStatement ps =null;
    // 结果集
    ResultSet rs = null;
    if (pageBean!=null&&pageBean.isPagination()) {//如果pageBean不等于空并且分页
      String countSql=getCountSql(sql);
      ps = conn.prepareStatement(countSql);
      rs = ps.executeQuery();
      if (rs.next()) {
        //得到总数
        pageBean.setTotal(rs.getObject("n").toString());
      }
      String pageSql=getPageSql(sql,pageBean);
      ps = conn.prepareStatement(pageSql);
      rs = ps.executeQuery();
    }else {//不分页
      conn = DBHepler.getConnection();
      ps = conn.prepareStatement(sql);
    }
    while (rs.next()) {
      //类实例
      T t = classes.newInstance();
      //拿到所有属性
      Field[] fields = classes.getDeclaredFields();
      for (Field fieldName : fields) {
        //打开访问权限
        fieldName.setAccessible(true);
        //为t赋值
        fieldName.set(t, rs.getObject(fieldName.getName()));
      }
      list.add(t);
    }
    return list;
  }
  /**得到符合条件的sql
   * @param sql
   * @param pageBean
   * @return
   */
  private String getPageSql(String sql, PageBean pageBean) {
    return sql + " limit "+pageBean.getStartIndex()+","+pageBean.getRows();
  }
  /**得到总数的sql
   * @param sql
   * @return
   */
  private String getCountSql(String sql) {
    return "select count(1) as n FROM ("+sql+") t";
  }
}

basedao的编写在上篇博客详细解释了——>后台通用分页

dao

package com.xqx.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.sun.xml.internal.ws.util.StreamUtils;
import com.xqx.entity.Book;
import com.xqx.util.DBHepler;
import com.xqx.util.PageBean;
import com.xqx.util.StringUtils;
/**
 * dao方法类
 * 
 * @author W许潜行
 *
 */
public class BookDao extends BaseDao<Book>{
  /**原始查询方法
   * @param book
   * @param pageBean
   * @return
   * @throws Exception
   */
  public List<Book> queryBook(Book book, PageBean pageBean) throws Exception {
    List<Book> list = new ArrayList<Book>();
    // 建立连接
    Connection conn = DBHepler.getConnection();
    String sql = "select *from t_mvc_book";
    String bname = book.getBname();
    if (!StringUtils.isBlank(bname)) {
      sql += " where bname like '%" + bname + "%' ";
    }
    // 执行sql语句
    PreparedStatement ps = conn.prepareStatement(sql);
    // 结果集
    ResultSet rs = ps.executeQuery();
    while (rs.next()) {
      list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price")));
    }
    return list;
  }
  /**使用通用模糊查询方法
   * @param book
   * @param pageBean
   * @return
   * @throws Exception
   */
  public List<Book> queryBook2(Book book, PageBean pageBean) throws Exception {
    String sql = "select *from t_mvc_book";
    String bname = book.getBname();
    if (!StringUtils.isBlank(bname)) {
      sql += " where bname like '%" + bname + "%' ";
    }
    return super.query(sql, Book.class, pageBean);
  }
  /**通用分页模糊查询
   * @param book
   * @param pageBean
   * @return
   * @throws Exception
   */
  public List<Book> queryBook3(Book book, PageBean pageBean) throws Exception {
    String sql = "select *from t_mvc_book";
    String bname = book.getBname();
    if (!StringUtils.isBlank(bname)) {
      sql += " where bname like '%" + bname + "%' ";
    }
    return super.query2(sql, Book.class, pageBean);
  }
  public static void main(String[] args) throws Exception {
    System.out.println("==================通用查询======================");
    Book book = new Book();
    //查询名称
    book.setBname("圣墟");
    PageBean pageBean = new PageBean();
    List<Book> listBook = new BookDao().queryBook2(book, pageBean);
    for (Book bookList : listBook) {
      System.out.println(bookList);
    }
  }
  @Test
  public void test() throws Exception {
    System.out.println("==================原始查询======================");
    Book book = new Book();
    //查询名称
    book.setBname("圣墟");
    PageBean pageBean = new PageBean();
    List<Book> listBook = new BookDao().queryBook2(book, pageBean);
    for (Book bookList : listBook) {
      System.out.println(bookList);
    }
  }
  @Test
  public void test1() throws Exception {
    System.out.println("==================通用查询======================");
    Book book = new Book();
    //查询名称
    book.setBname("圣墟");
    PageBean pageBean = new PageBean();
    List<Book> listBook = new BookDao().queryBook2(book, pageBean);
    for (Book bookList : listBook) {
      System.out.println(bookList);
    }
  }
  @Test
  public void test2() throws Exception {
    System.out.println("==================通用分页查询======================");
    Book book = new Book();
    //查询名称
    book.setBname("圣墟");
    PageBean pageBean = new PageBean();
    //页码
    pageBean.setPage(1);
    //条数
    pageBean.setRows(10);
    List<Book> listBook = new BookDao().queryBook3(book, pageBean);
    for (Book bookList : listBook) {
      System.out.println(bookList);
    }
  }
}

2.3 编写分页工具类

与后端的分页工具类相比添加了初始化方法和页码变化方法

  • setRequest(HttpServletRequest req) 方法从 HttpServletRequest 对象中获取请求参数,并设置到 PageBean 对象的相应属性中。通过调用该方法,可以将分页信息从请求中提取出来并初始化到 PageBean 对象
  • getPrevPage()、getNextPage() 和 getMaxPage() 方法分别用于计算上一页、下一页和最大页码,以便在分页导航栏中使用。
package com.xqx.util;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
/**
 * 分页工具类
 * 
 * @author W许潜行
 *
 */
public class PageBean {
  private int page = 1;// 页码
  private int rows = 10;// 页大小
  private int total = 0;// 总记录数
  private boolean pagination = true;// 是否分页
  // 上一次查询的url
  private String url;
  // 上一次查询所携带的查询条件
  private Map<String, String[]> parameterMap = new HashMap<String, String[]>();
  public String getUrl() {
    return url;
  }
  public void setUrl(String url) {
    this.url = url;
  }
  public Map<String, String[]> getParameterMap() {
    return parameterMap;
  }
  public void setParameterMap(Map<String, String[]> parameterMap) {
    this.parameterMap = parameterMap;
  }
  public PageBean() {
    super();
  }
  public int getPage() {
    return page;
  }
  public void setPage(int page) {
    this.page = page;
  }
  public int getRows() {
    return rows;
  }
  public void setRows(int rows) {
    this.rows = rows;
  }
  public int getTotal() {
    return total;
  }
  public void setTotal(int total) {
    this.total = total;
  }
  public void setTotal(String total) {
    this.total = Integer.parseInt(total);
  }
  public boolean isPagination() {
    return pagination;
  }
  public void setPagination(boolean pagination) {
    this.pagination = pagination;
  }
  /**
   * 获得起始记录的下标
   * 
   * @return
   */
  public int getStartIndex() {
    return (this.page - 1) * this.rows;
  }
  @Override
  public String toString() {
    return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
  }
  // 对pagebean进行初始化
  public void setRequest(HttpServletRequest req) {
    // 初始化jsp页面传递过来的当前页
    this.setPage(req.getParameter("page"));
    // 初始化jsp页面传递过来的页大小
    this.setRows(req.getParameter("rows"));
    // 初始化jsp页面传递过来是否分页
    this.setPagination(req.getParameter("pagination"));
    // 保留上一次的查询请求
    this.setUrl(req.getRequestURL().toString());
    // 保留上一次的查询条件
    this.setParameterMap(req.getParameterMap());
  }
  private void setPagination(String pagination) {
    // 只有填写了false字符串,才代表不分页
    this.setPagination(!"false".equals(pagination));
  }
  private void setRows(String rows) {
    if (StringUtils.isNotBlank(rows))
      this.setRows(Integer.valueOf(rows));
  }
  private void setPage(String page) {
    if (StringUtils.isNotBlank(page))
      this.setPage(Integer.valueOf(page));
  }
  // 上一页
  public int getPrevPage() {
    return this.page > 1 ? this.page - 1 : this.page;
  }
  // 下一页
  public int getNextPage() {
    return this.page < this.getMaxPage() ? this.page + 1 : this.page;
  }
  // 最大页
  public int getMaxPage() {
    return this.total % this.rows == 0 ? this.total / this.rows : (this.total / this.rows) + 1;
  }
}

2.4 自定义分页标签

tld

> 标签名为page 属性名为pageBean
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">
  <description>JSTL 1.1 core library</description>
  <display-name>JSTL core</display-name>
  <tlib-version>1.1</tlib-version>
  <short-name>x</short-name>
  <uri>http://jsp.xqx.cn</uri>
  <tag>
        <name>page</name>
        <tag-class>com.xqx.tag.PageTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>pageBean</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
</taglib>

tag

  • 有一个pageBean属性,用于存储分页信息。
  • 在JSP页面解析时会调用该方法doStartTag()。在该方法中,通过获取
    JspWriter对象,将生成的分页导航栏的HTML代码输出到JSP页面。
  • toHTML() 方法用于生成t通用分页导航栏的HTML代码
package com.xqx.tag;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import com.xqx.util.PageBean;
/**
 * @author W许潜行
 *
 */
public class PageTag 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='methodName' value='list'>");
    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></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();
  }
}

2.5 编写Servlet和Jsp

Servlet

package com.xqx.servlet;
import java.io.IOException;
import java.util.List;
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 com.xqx.dao.BookDao;
import com.xqx.entity.Book;
import com.xqx.util.PageBean;
/**
 * Servlet implementation class BookServlet
 */
@WebServlet("/book.action")
public class BookServlet extends HttpServlet {
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //dao方法
    BookDao bd=new BookDao();
    //分页工具
    PageBean pb = new PageBean();
    //初始化
    pb.setRequest(request);
    Book book = new Book();
    //名字模糊查询
    book.setBname(request.getParameter("bname"));
    try {
      // 调用模糊查询分页方法
      List<Book> listBook = bd.queryBook3(book, pb);
      // 将listBook pb 设置到请求属性中
      request.setAttribute("books", listBook);
      request.setAttribute("pageBean", pb);
      request.getRequestDispatcher("/bookList.jsp").forward(request, response);
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

Jsp

引入c标签和自定义标签遍历数据与分页导航栏

<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core”%>

<%@ taglib prefix=“x” uri=“http://jsp.xqx.cn”%>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="x" uri="http://jsp.xqx.cn"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
<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;
}
.page-item input, .page-item b {
  line-height: 38px;
  float: left;
  font-weight: 400;
}
.page-item.go-input {
  margin: 0 10px;
} 
</style>
</head>
<body>
  <form class="form-inline"
    action="${pageContext.request.contextPath }/book.action" method="post">
    <div class="form-group mb-2">
      <input type="text" class="form-control-plaintext" 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:forEach items="${books }" var="b">
      <tr>
        <td>${b.bid }</td>
        <td>${b.bname }</td>
        <td>${b.price }</td>
      </tr>
      </c:forEach>
    </tbody>
  </table>
  <!-- 分页导航栏 -->
  <x:page pageBean="${pageBean }"></x:page>
</body>
</html>

到这里就基本结束了,我们运行一下,搜索“圣”

结果出现了乱码情况,那编写一个的过滤器

2.6 编写过滤器

该过滤器的作用是在请求经过时,对请求参数和响应内容进行字符编码的处理,以解决中文乱码的问题。可以通过在 web.xml 文件中配置该过滤器,使其对所有请求进行过滤和处理。

package com.xqx.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;
/**
 * 中文乱码处理
 * @author W许潜行
 *
 */
@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();
    }
  }
}

好啦,今天的分享就到此为止!希望你看完本篇文章有所收获,祝你变得更强!!!

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
SQL 前端开发 Java
java通用分页前端(2)
java通用分页前端(2)
65 0
|
XML 前端开发 Java
JavaEE通用分页(前端实现)
JavaEE通用分页(前端实现)
64 0
|
3月前
|
前端开发 JavaScript
在 Vue3 + ElementPlus 项目中使用 computed 实现前端静态分页
本文介绍了在Vue3 + ElementPlus项目中使用`computed`属性实现前端静态分页的方法,并提供了详细的示例代码和运行效果。
160 1
在 Vue3 + ElementPlus 项目中使用 computed 实现前端静态分页
|
4月前
|
开发框架 前端开发 JavaScript
循序渐进VUE+Element 前端应用开发(30)--- ABP后端和Vue+Element前端结合的分页排序处理
循序渐进VUE+Element 前端应用开发(30)--- ABP后端和Vue+Element前端结合的分页排序处理
|
5月前
|
缓存 负载均衡 前端开发
SSMP整合案例第八步 前端页面的分页功能完善与维护和实现条件查询
SSMP整合案例第八步 前端页面的分页功能完善与维护和实现条件查询
45 1
|
4月前
|
前端开发
后端一次返回大量数据,前端做分页处理
后端一次返回大量数据,前端做分页处理
163 0
|
4月前
|
前端开发
Element UI 表格常用改造(表头添加注释、翻页连续序号【内含前端分页】)
Element UI 表格常用改造(表头添加注释、翻页连续序号【内含前端分页】)
197 0
|
6月前
|
前端开发 UED
🌟前端分页加载/懒加载预览PDF🌟
🌟前端分页加载/懒加载预览PDF🌟
|
6月前
|
前端开发 JavaScript
Element纯前端分页处理
Element纯前端分页处理
34 0
|
6月前
|
前端开发 JavaScript
vue实现通用分页控件,支持前端分页、后端分页。
vue实现通用分页控件,支持前端分页、后端分页。
90 1
下一篇
无影云桌面