在实际的项目中我们都需要使用到大量的数据分页,如何才能保证简洁、统一的页面风格,方便、简单的代码使用呢?在j2ee中的标签(Tag)为我们实现这一想法提供了一种方便的实现方式。
这里使用一个简单的例子来说明我的实现,具体的效果图为:
首先抽象出一个Page对象,它封装了我们分页的一些信息。
代码如下:
public class Page<T> {
private int pageNo=1;//当前第几页
private int pageSize=5;//页大小 默认每页为5
private int dataSize;//总数据大小
private int pageNumber;//共多少页
private int pageStart;
private int pageEnd;
private List<T> result;//当前页数据
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>//一些get、set方法...
}
然后我们需要创建一个标签类。
在分页中我们涉及到最主要的一个地方是url参数,有些情况下我们的参数不仅仅是只有分页信息的参数,还有一些其他的参数,如在某个带条件查询的情况下需要携带一些非分页参数。
这里我们可以考虑给分页标签添加一个分页参数标签来传递非分页参数的信息。
分页标签代码如下:
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
public class PageTag extends TagSupport{
private int pageNo;//第几页
private int pageSize;//页大小
private int dataSize;//总数据大小
private String url;//分页地址
private Map<String,String> parameters = new HashMap<String,String>(); //接收子标签的参数信息
@Override
public int doStartTag() throws JspException {
Iterator<String> it=parameters.keySet().iterator();
if(!url.contains("?")){
url=url+"?";
}
if(!url.endsWith("?")&&!url.endsWith("&")){
url=url+"&";
}
url=url+"pageSize="+pageSize;
while(it.hasNext()){
Object key=it.next();
String val=parameters.get(key);
if(!key.toString().equals("pageNo")&&!key.toString().equals("pageSize")){
if(!url.endsWith("?")&&!url.endsWith("&")){
url=url+"&";
}
url=url+key.toString()+"="+val;
}
}
StringBuilder sb=new StringBuilder("<div class='p_page'>");
try {
int pageNumber=dataSize/pageSize;
if(dataSize%pageSize!=0){
pageNumber=dataSize/pageSize+1;
}
sb.append("<a class='p_move' href='javascript:void(0);'>共"+pageNumber+"页/"+dataSize+"条</a>");
String href=url;
String classs="p_move pre_page";
if(pageNo<=1){//第一页
classs=classs+" dis_move";
href="javascript:void(0);";
}else{
if(!url.endsWith("?")&&!url.endsWith("&")){
url=url+"&";
}
href=url+"pageNo="+(pageNo-1);
}
if(pageNumber>1){
sb.append("<a class='"+classs+"' href="+href+"><i><<</i>上一页</a>");
}
if(pageNumber<=10){//小于等于10页时全部显示
for(int i=0;i<pageNumber;i++){
classs="p_num";
href=url;
if(pageNo==i+1){//如果是当前页
classs=classs+" p_now";
href="javascript:void(0);";
}else{
if(!url.endsWith("?")&&!url.endsWith("&")){
url=url+"&";
}
href=url+"pageNo="+(i+1);
}
sb.append("<a class='"+classs+"' href="+href+">"+(i+1)+"</a>");
}
}else{ //大于10页时显示当前页的前5和后4策略、超出页数向左向右移动
int s=pageNo-5;//当前页前显示5个分页格子
int e=pageNo+4;//当前页后面显示4个分页格子
if(s<=0){//如果开始的页数小于0,那么整体向后移动
int temp=Math.abs(s)+1;
s=s+temp;
e=e+temp;
}
if(e>pageNumber){//如果最后一个大于页数,那么整体向前移动
int temp=e-pageNumber;
s=s-temp;
e=e-temp;
}
for(int i=s;i<=e;i++){
classs="p_num";
href=url;
if(pageNo==i){//如果是当前页
classs=classs+" p_now";
href="javascript:void(0);";
}else{
if(!url.endsWith("?")&&!url.endsWith("&")){
url=url+"&";
}
href=url+"pageNo="+(i);
}
sb.append("<a class='"+classs+"' href="+href+">"+(i)+"</a>");
}
}
classs="p_move next_page";
href=url;
if(pageNo>=pageNumber){//如果是最后页
classs=classs+" dis_move";
href="javascript:void(0);";
}else{
if(!url.endsWith("?")&&!url.endsWith("&")){
url=url+"&";
}
href=url+"pageNo="+(pageNo+1);
}
if(pageNumber>0){
sb.append("<a class='"+classs+"' href="+href+">下一页<i>>></i></a>");
}
sb.append("</div>");
super.pageContext.getOut().write(sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
return EVAL_BODY_INCLUDE;
}
public int doEndTag() throws JspException {
return EVAL_PAGE;
}
public int getPageNo() {
return pageNo;
}
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getDataSize() {
return dataSize;
}
public void setDataSize(int dataSize) {
this.dataSize = dataSize;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
/**
* 传递url参数的map
* @param key
* @param value
*/
public void addValue(String key, String value) {
parameters.put(key, value);
}
}
分页参数标签代码如下:
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
public class ParameterTag extends TagSupport{
private String key;//参数名
private String value;//参数值
public int doStartTag() throws JspException {
PageTag pTag = (PageTag) this.getParent();
//调用父标签的addValue方法,给父标签中的map赋值
pTag.addValue(key,value);
return EVAL_BODY_INCLUDE;
}
public int doEndTag() throws JspException {
return EVAL_PAGE;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
1:在WEB-INF目录下创建一个分页的tld文件,如pagetag.tld。
类容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>p</short-name>
<uri>/pageTag</uri>
<tag>
<name>pageTag</name>
<tag-class>com.test.page.PageTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>pageNo</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>pageSize</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>dataSize</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>url</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- 作为分页标签中传递参数的子标签 -->
<tag>
<name>pageParam</name>
<span style="white-space:pre"> </span><!--这里和类的包名一致-->
<tag-class>com.test.page.ParameterTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>key</name>
<required>true</required>
<!-- rtexprvalue 是否允许表达式 不允许时${xxx}出错 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<!-- 标签中显示的参数名 -->
<name>value</name>
<!-- 参数必须 -->
<required>true</required>
<!-- rtexprvalue 是否允许表达式 不允许时${xx}出错 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
2:在web.xml中配置:
<taglib>
<taglib-uri>/pageTag</taglib-uri>
<taglib-location>pagetag.tld</taglib-location>
</taglib>
完成之后就可以在jsp页面中使用该标签了。
首先引入标签库
<%@taglib prefix="p" uri="/pageTag" %>
页面引用,这里需要自己创建一个page对象并给相应的属性赋值。(分页参数标签可不带。 url="${requestUrl}"这里的值可以写成相对路径如:xxx.action等)
<p:pageTag dataSize="${page.dataSize}" pageSize="${page.pageSize}" pageNo="${page.pageNo}" url="${requestUrl}">
<p:pageParam key="a" value="b"/>
<p:pageParam key="c" value="d"/>
</p:pageTag>
生成的url地址为:http://localhost:8080/test/test.action?pageSize=5&c=d&a=b&pageNo=1
如有其他需求可自行添加修改。
附带css样式如下:
.p_page{
text-align: right;
}
.p_page a{
text-decoration: none;
margin: 0 0 0 10px;
border: solid 1px #d9e4f3;
color: #3182b3;
display: inline-block;
text-align: center;
}
.p_page .dis_move{
border-color: #ddd;
color: #999;
cursor: no-drop;
}
.p_page .dis_move i{
color: #999;
}
.p_page .pre_page i{
margin: 0 10px 0 0px;
}
.p_page .next_page i{
margin: 0 5px 0 5px;
}
.p_page a i{
letter-spacing: -.5em;
font-family: \5B8B\4F53;
font-style: normal;
font-weight: 700;
color: #ff6600;
}
.p_page .p_now{
background:#28a3f0;
color:#FFFFFF;
}
.p_page a:HOVER{
color: #ff6600;
text-decoration: none;
}
.p_page .p_move{
width:80px;
}
.p_page .p_num{
width:30px;
}
之后就可以看到如前面的效果图了,有更好建议的你提给我把。