这一章将继续上一章的内容,完善自定义分页标签,上一章主要是重构-提取公用方法,这一章主要是封装分页标签
student.jsp
这个页面是分页标签封装之前
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>
head>
<body>
<h1>学生信息h1>
<form action="<%=request.getContextPath()%>/students" method="post">
<input type="text" name="sname">
<input type="submit" value="查询">
form>
<table border="1" style="width: 98%;">
<tr>
<td>学号td>
<td>姓名td>
<td>年龄td>
<td>备注td>
tr>
<c:forEach items="${students}" var="student">
<tr>
<td>${student.sid}td>
<td>${student.sname}td>
<td>${student.score}td>
<td>${student.clazz}td>
tr>
c:forEach>
table>
<div style="text-align: right; width:98%;">
第${pageBean.page}页
共${pageBean.total}条记录
<a href="javascript:goPage(1);">首页a>
<a href="javascript:goPage(${pageBean.previousPage});">上页a>
<a href="javascript:goPage(${pageBean.nextPage});">下页a>
<a href="javascript:goPage(${pageBean.totalPage});">尾页a>
第<input type="text" size="2" id="pageNumber" onkeypress="toPageNumber(event,this.value)"/>
<a href="javascript:goPage(document.getElementById('pageNumber').value);">GOa>
div>
<form action="${pageBean.url}" id="pagingForm" method="post">
<input type="hidden" name="page" value="${pageBean.page}"/>
<input type="hidden" name="sname" value="<%=request.getParameter("sname")%>"/>
form>
body>
<script>
function goPage(pageNum){
let form = document.getElementById("pagingForm");
let lastPage = '${pageBean.totalPage}';
if(pageNum > lastPage){
pageNum = lastPage;
}
if(pageNum < 1){
pageNum = 1;
}
form.page.value = pageNum;
form.submit();
}
function toPageNumber(event,pn){
//debugger;
if(event.keyCode == 13){
let form = document.getElementById("pagingForm");
form.page.value = pn;
form.submit();
}
}
script>
html>
准备一个servlet用于处理请求,获取数据库中的数据,并转发到结果显示页面。
StudentServlet .class
package com.zking.mymvc.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.zking.mymvc.model.Student;
import com.zking.mymvc.util.PageBean;
import com.zking.mymvc.util.StudentDao;
@WebServlet("/students")
public class StudentServlet extends HttpServlet {
private StudentDao dao = new StudentDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PageBean pageBean = new PageBean();
pageBean.setRequest(req);
//获取查询参数
String sname = req.getParameter("sname");
List<Student> students = dao.getStudent02(sname, pageBean);
req.setAttribute("students", students);
System.out.println("dopost .......... ");
req.getRequestDispatcher("/student2.jsp").forward(req, resp);
}
}
EncodingFiter .class
package com.zking.mymvc.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 zjjt
*
*/
@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();
}
}
}
在web.xml文件里面写出
为了方便代码的复用,及可维护性,我们将分页功能封装了一个自定义标签(其实就是将原来写在页面中的代码,通过移入到自定义标签中去实现),开发自定义标签分成三步:
编写助手类
编写标签描述文件
在页面上引入标签库,并使用
1) 编写助手类
package com.zking.mymvc.tag;
import java.io.IOException;
import java.util.Map;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import com.zking.mymvc.util.PageBean;
/**
* 助手类
* @author zjjt
*
*/
public class PagingTag extends BodyTagSupport{
private PageBean pageBean;
public void setPageBean(PageBean pageBean) {
this.pageBean = pageBean;
}
@Override
public int doStartTag() {
JspWriter out = this.pageContext.getOut();//得到一个写出对象
try {
out.print(buildHtml());//直接写出
} catch (IOException e) {
e.printStackTrace();
}
return SKIP_BODY;
}
//构造分页的页面输出
private String buildHtml() {
String pagingTool="\r\n"
+ " 第"+pageBean.getPage()+"页 \r\n"
+ " 共"+pageBean.getTotal()+"条记录 \r\n"
+ " 首页 \r\n"
+ " +pageBean.getPreviousPage()+");\">上页 \r\n"
+ " +pageBean.getNextPage()+");\">下页 \r\n"
+ " +pageBean.getTotalPage()+");\">尾页 \r\n"
+ " 第 \r\n"
+ " GO\r\n"
+ " ";
//构建隐藏表单,用于在分页时传递分页参数
String hiddenForm = "
+ "";
Map<String, String[]> parameterMap = pageBean.getParameterMap();//获取所有的参数
//循环所有的参数,并为所有的参数生成隐藏表单
for(Map.Entry<String, String[]> param: parameterMap.entrySet()) {
String paramName = param.getKey();//获取到一个名称
if("page".equals(paramName)) continue;//直接跳过
String[] values = param.getValue();//获取参数值,一个属性可能有多个值所以用数组
for(String val: values) {//上面是数组
hiddenForm += "";
}
}
hiddenForm += "";
String js="";
return pagingTool+hiddenForm+js;
}
}
2) 标签库描述文件中添加paging标签
<tag>
<name>paging</name>
<tag-class>com.zking.mymvc.tag.PagingTag</tag-class>
<body-content>empty</body-content>
<description>分页标签</description>
<attribute>
<name>pageBean</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
3) 使用分页标签
首先在页面中引入标签
<%@taglib prefix="z" uri="/zking" %>
将原来的分页功能,替换为标签即可
<z:paging pageBean="${pageBean}"/>
4)封装之后的student.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 引入的C标签 -->
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- 引入自定义标签库 -->
<%@taglib prefix="z" uri="/zking" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>学生信息</h1>
<form action="<%=request.getContextPath()%>/students" method="post">
<input type="text" name="sname">
<input type="submit" value="查询">
</form>
<table border="1" style="width: 98%;">
<tr>
<td>学号</td>
<td>姓名</td>
<td>年龄</td>
<td>备注</td>
</tr>
<c:forEach items="${students}" var="student">
<tr>
<td>${student.sid}</td>
<td>${student.sname}</td>
<td>${student.score}</td>
<td>${student.clazz}</td>
</tr>
</c:forEach>
</table>
<z:paging pageBean="${pageBean}"/>
</body>
</html>