通用分页(二)

1. PageBean
分页三要素
page 页码 视图层传递过来
rows 页大小 视图层传递过来
total 总记录数 后台查出来

pagination 是否分页 视图层传递过来

2. 后台
2.1 entity
2.2 dao
第一次查满足条件的总记录数
第二次查指定页码并满足条件的记录
二次查询的条件要一致
2.3 控制层
Servlet

3. 视图层
PageTag

如何将上一次查询请求再发一次
String contextPath = req.getContextPath();//根目录
String url = req.getServletPath();//请求的地址
req.getRequestURL() //获取请求全路径
Map<String, String[]> parameterMap = req.getParameterMap();//获得请求中的所有参数

注1:不能将分页表单嵌套到其它表单中,否则不能提交表单!!!
不能将分页表单嵌套到其它表单中,否则不能提交表单!!!
不能将分页表单嵌套到其它表单中,否则不能提交表单!!!

4. junit
java单元测试/白盒测试
setUp
tearDown
测试用例

  package com.luoxiaogang.util;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

/**
 * 分页工具类
 *
 */
public class PageBean {

	private int page = 1;// 页码

	private int rows = 10;// 页大小

	private int total = 0;// 总记录数

	private boolean pagination = true;// 是否分页
	
	Map<String, String[]> paMap=new HashMap<>();
	private String url;
    
	public void setRequest(HttpServletRequest req) {
		
//		保存上一次请求所携带的参数
		this.setPaMap(req.getParameterMap());
		this.setUrl(req.getRequestURL().toString());
//		在jsp页面控制是否分页
		this.setPagination(req.getParameter("Pagination"));
//	        在jsp页面控制一页多少条
		this.setRows(req.getParameter("rows"));
//		默认第几页
		this.setPage(req.getParameter("page"));
	}
	
	
	
	public void setPage(String page) {
		// TODO Auto-generated method stub
		this.page=StringUtils.isNotBlank(page)? Integer.valueOf(page):this.page;
	}



	public void setPagination(String parameter) {
		// TODO Auto-generated method stub
		this.pagination=StringUtils.isNotBlank(parameter)? !"false".equals(parameter):this.pagination;
	}



	public void setRows(String rows) {
		// TODO Auto-generated method stub
		this.rows=StringUtils.isNotBlank(rows)?Integer.valueOf(rows):this.rows;
		
	}



	public Map<String, String[]> getPaMap() {
		return paMap;
	}

	public void setPaMap(Map<String, String[]> paMap) {
		this.paMap = paMap;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	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 + "]";
	}
   
	/**
	 * 获取最大页数
	 * @return
	 */
	public int getMaxPage() {
		return this.total%this.rows==0?this.total/this.rows:this.total/this.rows+1;
	}
	/**
	 * 获取下一页
	 * @return
	 */
	public int getNextPage() {
		return this.page<this.getMaxPage()?this.page+1:this.page;
	}
	/**
	 * 获取上一页
	 * @return
	 */
	public int getpreviousPage() {
		return this.getPage()>1?this.page-1:this.page;
	}
}

**1.2 EncodingFiter.java

package com.luoxiaogang.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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 中文乱码处理
 * 
 */
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();
		}
	}

}

这段代码放在xml文件的最前面,方便过滤的servlet:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>web_02</display-name>
  <filter>
  <filter-name>encodingFiter</filter-name>
  <filter-class>com.houyitao.util.EncodingFiter</filter-class>
  </filter>
  <filter-mapping>
  <filter-name>encodingFiter</filter-name>
  <url-pattern>/bookservlet</url-pattern>
  </filter-mapping>

</web-app>

2. 后台
PageTag 标签助手类

package com.luoxiaogang.tag;

import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;

import com.houyitao.util.PageBean;

public class PageTag extends BodyTagSupport{

	private static final long serialVersionUID = 2570317524495960725L;
    
	private PageBean pageBean;

	public PageBean getPageBean() {
		return pageBean;
	}

	public void setPageBean(PageBean pageBean) {
		this.pageBean = pageBean;
	}
	
	
	@Override
	public int doStartTag() throws JspException {
		// TODO Auto-generated method stub
		JspWriter out = pageContext.getOut();
		try {
			out.print(toHTML());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return super.doStartTag();
	}

	private String toHTML() {
		// TODO Auto-generated method stub
		StringBuilder sb=new StringBuilder();
		
//		拼接下一次发送请求所要提交的隐藏form表达
		sb.append("<form id='pageBeanForm' action='"+pageBean.getUrl()+"' method='post'>");
		sb.append("<input type='hidden' name='page'>");
		Map<String, String[]> paMap = pageBean.getPaMap();
		if(paMap!=null && paMap.size()>0) {
			Set<Entry<String, String[]>> entrySet = paMap.entrySet();
		for (Entry<String, String[]> entry : entrySet) {
//			上一次请求可能携带页码name=page的参数,但是该参数在前面已经单独赋值
//			为什么要单独赋值呢?因为上一次请求是第一页的数据,下一次可能是第二页,
//			以为这前后请求page对应的值是不一样的,需要单独赋值
			if(!"page".equals(entry.getKey())) {
				for(String val:entry.getValue()) {
					sb.append("<input type='hidden' name='"+entry.getKey()+"'value='"+val+"'>");
				}
			}
		}
		}
		sb.append("</form>");
		
	
		
		
//		拼接分页条
		sb.append("<div style='text-align: right; font-size: 12px;'>");
		sb.append("每页"+pageBean.getRows()+"条,共"+pageBean.getTotal()+"条,第"+pageBean.getPage()+"页,共"+pageBean.getMaxPage()+"页&nbsp;&nbsp;");
		sb.append(" <a href='javascript:gotoPage(1)'>首页</a>&nbsp;&nbsp;<a");
		sb.append(" href='javascript:gotoPage("+pageBean.getpreviousPage()+")'>上一页</a>&nbsp;&nbsp;<a");
		sb.append(" href='javascript:gotoPage("+pageBean.getNextPage()+")'>下一页</a>&nbsp;&nbsp;<a");
		sb.append(" href='javascript:gotoPage("+pageBean.getMaxPage()+")'>尾页</a>&nbsp;&nbsp;<input type='text'");
		sb.append(" id='skipPage'");
		sb.append(" style='text-align: center; font-size: 12px; width: 50px;'>&nbsp;&nbsp;<a");
		sb.append(" href='javascript:skipPage()'>Go</a>");
		sb.append(" </div>");
		
//		拼接分页所需要的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)>maxPage){");
		sb.append(" alert('请输入1~N的数字');");
		sb.append(" return;");
		sb.append(" }");
		sb.append(" gotoPage(page);");
		sb.append(" }");
		sb.append(" </script>");
	
		return sb.toString();
	}
	
}

2.把PageBean加入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">
    
  <description>JSTL 1.1 core library</description>
  <display-name>JSTL core</display-name>
  <tlib-version>1.1</tlib-version>
  <short-name>c</short-name>
  <uri>/houyitao</uri>


  <tag>
  <!-- 标签库中的标签(类似c:set   c:out的定义) -->
   
    <name>page</name>
    <!-- 是标签运行具体的代码,也就是助手类,下面填写的是助手类的全路径名 -->
    <tag-class>com.houyitao.tag.PageTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <!-- 该标签的属性 -->
        <name>pageBean</name>
        <!-- 该标签的是否必填 -->
        <required>true</required>
         <!-- 该标签的是否支持表达式 -->
        <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>
</taglib>

2.3导入自定义分页标签

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 <!-- 自定义分页标签 -->
<%@ taglib uri="/houyitao" prefix="z"

2.4 控制层

package com.luoxiaogang.web;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.houyitao.dao.Book;
import com.houyitao.dao.BookDao;
import com.houyitao.util.PageBean;

public class BookServlet extends HttpServlet {
	
	private  BookDao bookDao=new BookDao();

	private static final long serialVersionUID = -4405443018425237315L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		
		String bname=req.getParameter("bname");
		Book book=new Book();
		book.setBname(bname);
//		Map<String, String[]> parameterMap = req.getParameterMap();
//		StringBuffer url = req.getRequestURL();
		PageBean pageBean=new PageBean();
		try {
			pageBean.setRequest(req);
			List<Book> list = this.bookDao.list(book, pageBean);
		    req.setAttribute("bookList", list);
		    req.setAttribute("pageBean", pageBean);
		    req.getRequestDispatcher("NewFile.jsp").forward(req, resp);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

配置 Servlet:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>web_02</display-name>
  <filter>
  <filter-name>encodingFiter</filter-name>
  <filter-class>com.houyitao.util.EncodingFiter</filter-class>
  </filter>
  <filter-mapping>
  <filter-name>encodingFiter</filter-name>
  <url-pattern>/bookservlet</url-pattern>
  </filter-mapping>
  
 <servlet>
 <servlet-name>bookServlet</servlet-name>
 <servlet-class>com.houyitao.web.BookServlet</servlet-class>
 </servlet>
 <servlet-mapping>
 <servlet-name>bookServlet</servlet-name>
 <url-pattern>/bookservlet</url-pattern>
 </servlet-mapping>
</web-app>

3.画页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 <!-- 自定义分页标签 -->
<%@ taglib uri="/houyitao" prefix="z" %>
<!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">
<title>Insert title here</title>
</head>
<body>
<h2>小说目录</h2>
	<br>
	<form action="${pageContext.request.contextPath}/bookservlet"
		method="post">
		书名:<input type="text" name="bname"> <input type="submit"
			value="确定">
			<!-- 是否分页 -->
			<input type="hidden" name="pagination" value="false"> 
			
			<!-- 显示多少页 -->
			 <input type="hidden" name="rows" value="20"> 

	</form>
	<table border="1" width="100%">
		<tr>
			<td>编号</td>
			<td>名称</td>
			<td>价格</td>
		</tr>
		<c:forEach items="${bookList }" var="b">
			<tr>
				<td>${b.bid }</td>
				<td>${b.bname }</td>
				<td>${b.price }</td>
			</tr>
		</c:forEach>
	</table>
<z:page pageBean="${pageBean }"></z:page>
	
	
</body>
</html>

结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45177212/article/details/93394872