欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JSP通用分页框架

程序员文章站 2023-10-27 15:22:10
写一个通用的分页框架,这样在项目里面如果想实现分页功能,只需要稍加改动参数就可以实现分页处理了。这样写了会节省很多时间。 一.分页类 既然要分页那么我们就要考虑建一个通...

写一个通用的分页框架,这样在项目里面如果想实现分页功能,只需要稍加改动参数就可以实现分页处理了。这样写了会节省很多时间。

一.分页类

既然要分页那么我们就要考虑建一个通用的分页类,里面需要的参数一般有:

总页数 totalpage

总共记录数 totalrecord

每页显示数 pagesize

当前页pageindex

承载当前页数据的集合 list datas

完整代码:page.java

import java.util.list;
public class pager<e> {
/**
* 总共页数
*/
private int totalpages;
/**
* 总共记录数
*/
private int totalrecords;
/**
* 每页显示数量
*/
private int pagesize;
/**
* 当前页
*/
private int pageindex;
/**
* 当前页数据集合
*/
private list<e> datas;
public void settotalpages(int totalpages) {
this.totalpages = totalpages;
}
public void settotalrecords(int totalrecords) {
this.totalrecords = totalrecords;
}
public void setpagesize(int pagesize) {
this.pagesize = pagesize;
}
public void setpageindex(int pageindex) {
this.pageindex = pageindex;
}
public void setdatas(list<e> datas) {
this.datas = datas;
}
public int gettotalpages() {
return totalpages;
}
public int gettotalrecords() {
return totalrecords;
}
public int getpagesize() {
return pagesize;
}
public int getpageindex() {
return pageindex;
}
public list<e> getdatas() {
return datas;
}
}

二.用户类

这里以查询用户来做分页为例,所以就需要一个用户类

用户号 userid

用户姓名 username

用户密码 password

注册时间 regdate

完整代码

import java.sql.timestamp;
public class user {
private int userid;//用户id
private string username;//用户名
private string password;//密码
private timestamp regdate;//注册时间
public int getuserid() {
return userid;
}
public void setuserid(int userid) {
this.userid = userid;
}
public string getusername() {
return username;
}
public void setusername(string username) {
this.username = username;
}
public string getpassword() {
return password;
}
public void setpassword(string password) {
this.password = password;
}
public timestamp getregdate() {
return regdate;
}
public void setregdate(timestamp regdate) {
this.regdate = regdate;
}
}

三.threadlocal提取公用参数

先说如果不提取公共参数,比如pagesize,pageindex,那么我们的查询方法应该是这样子:

public void getusers(string name,int pagesize,int pageindex)

如果以后再增加参数,无疑这里的参数会变的很多,所以我们利用threadlocal把pagesize和pageindex提取出来.

先写这个类

public class systemcontext {
//页大小
private static threadlocal<integer> pagesize = new threadlocal<>();
//当前页
private static threadlocal<integer> pageindex = new threadlocal<>();
public static integer getpagesize() {
return pagesize.get();
}
public static void removepagesize(){
pagesize.remove();
}
public static void setpagesize(int _pagesize) {
pagesize.set(_pagesize);
}
public integer getpageindex() {
return pageindex.get();
}
public void setpageindex(int _pageindex) {
pageindex.set(_pageindex);
}
public static void removepageindex(){
pageindex.remove();
}
}

对于threadlocal,这个变量会在线程中一直存在,那么我们就可以在向服务器发送请求的时候添加参数,服务器返回数据的时候移除参数,一来一回的话,自然而然可以用过滤器

那么过滤器如下:

import com.dao.systemcontext;
import javax.servlet.*;
import java.io.ioexception;
public class systemfilter implements filter{
int pagesize;
int pageindex = 1;
@override
public void init(filterconfig filterconfig) throws servletexception {
try {
pagesize = integer.parseint(filterconfig.getinitparameter("pagesize"));
} catch (numberformatexception e) {
pagesize = 15;
}
}
@override
public void dofilter(servletrequest servletrequest, servletresponse servletresponse, filterchain filterchain) throws ioexception, servletexception {
try {
pageindex = integer.parseint(servletrequest.getparameter("pageindex"));
}catch (numberformatexception e){
//什么也不做,pageindex=1
}
try {
//开始请求的时候配置参数
systemcontext.setpagesize(pagesize);
systemcontext.setpageindex(pageindex);
filterchain.dofilter(servletrequest,servletresponse);
}finally {
//请求返回的时候移除参数
systemcontext.removepageindex();
systemcontext.removepagesize();
}
}
@override
public void destroy() {
}
}

用了过滤器,自然要在web.xml中配置过滤器

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<filter>
<filter-name>systemfilter</filter-name>
<filter-class>com.filter.systemfilter</filter-class>
<!--配置没页大小-->
<init-param>
<param-name>pagesize</param-name>
<param-value>15</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>systemfilter</filter-name>
<!--这里配置需要分页的页面-->
<url-pattern>/index.jsp</url-pattern>
</filter-mapping>
</web-app>

这样的好处不言而喻,结构清晰,修改方便.接下来是分页代码

四.分页代码

分页代码应该写一个接口和实现类的,这里演示项目就写在了一起

import com.util.pager;
import com.util.user;
import java.sql.*;
import java.util.arraylist;
import java.util.list;
public class userdao {
private connection conn = null;
private resultset rs = null;
private preparedstatement ps = null;
// public static void main(string[] args) {
// userdao dao = new userdao();
// dao.getusers("",15,1);
// dao.close();
// }
public userdao() {
string drivername = "com.mysql.jdbc.driver";
string url = "jdbc:mysql://localhost:3306/fenyedemo";
string user = "root";string password = "123456";
try {
class.forname(drivername);
conn = drivermanager.getconnection(url,user,password);
} catch (classnotfoundexception e) {
system.out.println("没有发现驱动");
e.printstacktrace();
} catch (sqlexception e) {
system.out.println("获取连接失败");
e.printstacktrace();
}
}
/**
* 具体分页实现代码
* @param name 查询条件
* @return
*/
public pager getusers(string name){
//获取分页参数
int pagesize = systemcontext.getpagesize();
int pageindex = systemcontext.getpageindex();
//分页具体sql语句
string sql = "select * from user ";
string sqlcount = "select count(*) from user ";
if (name!=null && !name.trim().equals("")){
sql += "where username like %"+name+"%";
sqlcount += "where username like %"+name+"%";
}
sql += " limit ?,?";
//存放当前页的集合
list<user> datas = new arraylist<>();
//存放当前分页的集合
pager<user> pages = new pager<>();
user usertemp = null;
try {
ps = conn.preparestatement(sql);
if(pageindex<=0) pageindex=1;
//设置参数
ps.setint(1,(pageindex-1)*pagesize);
ps.setint(2,pagesize);
rs = ps.executequery();
//循环取出,添加到datas中
while (rs.next()){
usertemp = new user();
usertemp.setuserid(rs.getstring("id"));
usertemp.setusername(rs.getstring("username"));
usertemp.setpassword(rs.getstring("password"));
usertemp.setregdate(rs.gettimestamp("regdate"));
datas.add(usertemp);
}
//最后设置pages
pages.setpageindex(pageindex);
pages.setpagesize(pagesize);
ps = conn.preparestatement(sqlcount);
rs = ps.executequery();
while(rs.next()){
pages.settotalrecords(rs.getint(1));
pages.settotalpages((rs.getint(1)-1)/pagesize+1);
}
pages.setdatas(datas);
} catch (sqlexception e) {
system.out.println("获取出错");
e.printstacktrace();
}
return pages;
}
public void close(){
try {
if (rs!=null) rs.close(); rs = null;
if (ps!=null) ps.close(); ps = null;
if (conn!=null) conn.close(); conn = null;
} catch (sqlexception e) {
system.out.println("关闭失败");
e.printstacktrace();
}
}
}

五.jsp测试页面

普通页面就是显示数据,这个很简单,代码如下

<%@ page import="com.dao.userdao" %>
<%@ page import="com.util.pager" %>
<%@ page import="com.util.user" %>
<%@ page import="java.util.iterator" %>
<%@ page contenttype="text/html;charset=utf-8" language="java" %>
<%
string condition = request.getparameter("condition");
userdao userdao = new userdao();
pager<user> pages = null;
if (condition!=null && !condition.trim().equals("")){
pages = userdao.getusers(condition);
}else {
pages = userdao.getusers(null);
}
userdao.close();
%>
<html>
<head>
<title>测试用例</title>
</head>
<body>
<h1 align="center">分页测试</h1>
<table align="center" border="1" width="700">
<tr>
<td colspan="100%">
<form method="get" action="index.jsp">
<input type="text" name="condition">
<input type="submit" value="查询">
</form>
</td>
</tr>
<tr>
<th>id</th>
<th>username</th>
<th>password</th>
<th>data</th>
</tr>
<%
for (iterator it = pages.getdatas().iterator(); it.hasnext() ; ) {
user usertemp = (user) it.next();
%>
<tr>
<td><%=usertemp.getuserid()%></td>
<td><%=usertemp.getusername()%></td>
<td><%=usertemp.getpassword()%></td>
<td><%=usertemp.getregdate()%></td>
</tr>
<% }%>
</table>
</body>
</html>

此时已经有一些效果了

 JSP通用分页框架

六.jsp页面添加控制选项

添加控制选项这里使用分页框架pager-taglib,也是为了更好的支持通用性.

首先在index.jsp页面查询之后静态引入一个新的页面,作为底部控制页面

使用方法,就是去下载相应的jar,然后引入到项目的lib中即可

JSP通用分页框架

<tr><td colspan="100%">
<jsp:include page="fenye.jsp">
<jsp:param name="items" value="<%=pages.gettotalrecords()%>"/>
<jsp:param name="maxpageitems" value="<%=pages.getpagesize()%>"/>
<jsp:param name="maxindexpages" value="10"/>
<jsp:param name="params" value="condition"/>
</jsp:include>
</td></tr>

下面开始写fenye.jsp

<%@ page contenttype="text/html;charset=utf-8" language="java" pageencoding="utf-8" %>
<%
int items = integer.parseint(request.getparameter("items"));
int maxpageitems = integer.parseint(request.getparameter("maxpageitems"));
int maxindexpages = integer.parseint(request.getparameter("maxindexpages"));
string params = request.getparameter("params");
%>
<%--引入分页框架--%>
<%@taglib prefix="pg" uri="http://jsptags.com/tags/navigation/pager" %>
<%--参数依次是项目总数 每页显示数量 下方菜单显示数 当前页curpage--%>
<pg:pager items="<%=items%>" maxpageitems="<%=maxpageitems%>" maxindexpages="<%=maxindexpages%>" export="curpage=pagenumber">
<pg:param name="<%=params%>"/>
<pg:first>
<a href="<%=pageurl%>">首页</a>
</pg:first>
<pg:prev>
<a href="<%=pageurl%>">上一页</a>
</pg:prev>
<pg:pages>
<%
if(curpage==pagenumber) {
%>
[<%=pagenumber %>]
<%
} else {
%>
<a href="<%=pageurl%>"><%=pagenumber %></a>
<%
}
%>
</pg:pages>
<pg:next>
<a href="<%=pageurl %>">下一页</a>
</pg:next>
<pg:last>
<a href="<%=pageurl %>">尾页</a>
</pg:last>
</pg:pager>

分页设计基本就是上面框架,重点是参数传递,这里参数传递利用静态引入的时候,配置jsp:param,然后到fenye,jsp中再取出.
其中pager-taglib中有一个标签是”/>,这个就是针对我的查询条件传递过来的参数,如果没传递,那么查询的话点击下一页也会出错,这里还有一个问题就是编码问题,pager-taglib默认编码是gb2312,你可以重新打包文件编译,也可以在tomcat的server.xml文件中配置urlencording=”utf-8”,这样就会没问题了.

JSP通用分页框架

七.总结

这样的一个框架,如果其他需要实现分页的就可以直接套用了,建立相应的实体类,写好分页代码,直接套用systemcontex.java和systemfilter.java(记得在web.xml配置相应的过滤文件),再jsp中可以直接使用fenye.jsp,这样就会省下很多麻烦