您的位置:首页 > 编程语言 > Java开发

STRUTS2自定义分页标签及过程中的问题

2012-12-25 00:25 387 查看

分页标签的开发

一直想写一个自己用的顺手的分页标签。网上的标签大部分都是在标签内部自成体系,不方便和页面上的查询条件结合在一起,即使有这样的标签,也不一定符合自己的实际需要。在这种需求的驱使下,决定写一个自己的分页标签,能够方便的和页面查询结合在一起,也能满足项目中的大部分需要。

在参考网上其他人的自定义分页标签的基础上,加上自己的一些个性化需求,完成了自定义分页标签的编写。分页标签的样式如下:



分页标签分为四部分:第一部分是记录数和总页数;第二部分是分页页码;第三部分是修改设置每页显示的记录数;第四部分是直接输入页码跳转。

STRUTS2下的自定义标签开发细节就不再复述,简单描述一下开发过程:

第一步:建立一个WEB工程
第二部:java部分的代码和普通WEB开发一样,路径在src目录的具体包中;
第三部:tld文件放置在/WEB-INF/下。

通过上述步骤的完成后,就可以直接利用建立的工程进行测试标签是否正确。多的不说了,直接把代码贴出来:

PagerTag.java

/**
* TODO
* Struts2Pager.java
* Administrator2012-12-18
*/
package com.citybug.tag;

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

import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport;

import com.opensymphony.xwork2.util.ValueStack;

/**
* @author Administrator
*
*/
public class PagerTag extends ComponentTagSupport {
/**
*
*/
private static final long serialVersionUID = 1L;
private String pageSize;
private String pageNo;
private String recordCount;
private String pageCount;
private String recordNum;
private String showChangePageSize;
private String showJumpPage;
private String formId;

public String getPageSize(){
return pageSize;
}

public void setPageSize(String pageSize){
this.pageSize=pageSize;
}

public String getPageNo(){
return pageNo;
}

public void setPageNo(String pageNo){
this.pageNo=pageNo;
}

public String getRecordCount(){
return recordCount;
}

public void setRecordCount(String recordCount){
this.recordCount=recordCount;
}

public String getPageCount(){
return pageCount;
}

public void setPageCount(String pageCount){
this.pageCount=pageCount;
}

public String getShowChangePageSize(){
return showChangePageSize;
}

public void setShowChangePageSize(String showChangePageSize){
this.showChangePageSize=showChangePageSize;
}

public String getShowJumpPage(){
return showJumpPage;
}

public void setShowJumpPage(String showJumpPage){
this.showJumpPage=showJumpPage;
}

public String getFormId(){
return formId;
}

public void setFormId(String formId){
this.formId=formId;
}

public String getRecordNum(){
return recordNum;
}

public void setRecordNum(String recordNum){
this.recordNum=recordNum;
}

@Override
public Component getBean(ValueStack arg0, HttpServletRequest arg1,
HttpServletResponse arg2) {
return new Pager(arg0,arg1);
}

protected void populateParams(){
super.populateParams();
Pager pager=(Pager)component;
pager.setPageNo(pageNo);
pager.setPageSize(pageSize);
pager.setRecordCount(recordCount);
pager.setPageCount(pageCount);
pager.setShowChangePageSize(showChangePageSize);
pager.setShowJumpPage(showJumpPage);
pager.setFormId(formId);
pager.setRecordNum(recordNum);
}
}


Pager.java

/**
* TODO
* Pager.java
* Administrator2012-12-18
*/
package com.citybug.tag;

import java.io.IOException;
import java.io.Writer;
import java.util.Enumeration;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.StrutsStatics;
import org.apache.struts2.components.Component;
import org.apache.struts2.dispatcher.StrutsRequestWrapper;

import com.opensymphony.xwork2.util.ValueStack;
/**
* @author Administrator
*
*/
public class Pager extends Component {
private HttpServletRequest request;
private String pageNo;   //当前页码
private String pageSize;	//每页记录数
private String recordCount;   //总记录数
private String pageCount;	  //总页数
private String showChangePageSize;
private String showJumpPage;
private String formId;
private String recordNum;

public HttpServletRequest getRequest() {
return request;
}

public void setRequest(HttpServletRequest request) {
this.request = request;
}

public String getPageNo(){
return pageNo;
}

public void setPageNo(String pageNo){
this.pageNo=pageNo;
}

public String getPageSize(){
return pageSize;
}

public void setPageSize(String pageSize){
this.pageSize=pageSize;
}

public String getRecordCount(){
return recordCount;
}

public void setRecordCount(String recordCount){
this.recordCount=recordCount;
}

public String setPageCount(){
return pageCount;
}

public void setPageCount(String pageCount){
this.pageCount=pageCount;
}

public Pager(ValueStack arg0, HttpServletRequest request) {
super(arg0);
this.request = request;
}

public String getShowChangePageSize(){
return showChangePageSize;
}

public void setShowChangePageSize(String showChangePageSize){
this.showChangePageSize=showChangePageSize;
}

public String getShowJumpPage(){
return showJumpPage;
}

public void setShowJumpPage(String showJumpPage){
this.showJumpPage=showJumpPage;
}

public String getFormId(){
return formId;
}

public void setFormId(String formId){
this.formId=formId;
}

public String getRecordNum(){
return recordNum;
}

public void setRecordNum(String recordNum){
this.recordNum=recordNum;
}

@Override
public boolean end(Writer writer,String body) {
boolean result = super.start(writer);
int iPageNo;
int iRecordCount;
int iPageCount;
int iPageSize;
boolean bShowChangePageSize;
boolean bShowJumpPage;
StringBuilder sb = new StringBuilder();
try {
//从ValueStack中取出数值
Object obj=this.getStack().findValue(pageNo);
pageNo = String.valueOf((Integer)obj);
obj=this.getStack().findValue(recordCount);
recordCount = String.valueOf((Integer)obj);

obj=this.getStack().findValue(pageSize);
pageSize=String.valueOf((Integer)obj);
obj=this.getStack().findValue(showChangePageSize);
bShowChangePageSize=Boolean.valueOf(String.valueOf(obj));
obj=this.getStack().findValue(recordNum);
recordNum=String.valueOf((Integer)obj);
obj=this.getStack().findValue(showJumpPage);
bShowJumpPage=Boolean.valueOf(String.valueOf(obj));

iPageSize=Integer.valueOf(pageSize);
iPageNo=Integer.valueOf(pageNo);
iRecordCount=Integer.valueOf(recordCount);
iPageCount=(iRecordCount+iPageSize-1)/iPageSize;
sb.append("<style type=\"text/css\">");
sb.append(".pagination {padding: 5px;float:right;font-size:10px;}");
sb.append(".pagination a, .pagination a:link, .pagination a:visited {padding:2px 5px;margin:2px;border:1px solid #aaaadd;text-decoration:none;color:#006699;}");
sb.append(".pagination a:hover, .pagination a:active {border: 1px solid #ff0000;color: #000;text-decoration: none;}");
sb.append(".pagination span.current {padding: 2px 5px;margin: 2px;border: 1px solid #ff0000;font-weight: bold;background-color: #ff0000;color: #FFF;}");
sb.append(".pagination span.disabled {padding: 2px 5px;margin: 2px;border: 1px solid #eee; color: #ddd;}");
sb.append("</style>\r\n");
sb.append("<div class=\"pagination\">\r\n");
if(iRecordCount == 0){
sb.append("<strong>没有可显示的项目</strong>\r\n");
}else{
//页号越界处理
if(iPageNo > iPageCount){      iPageNo = iPageCount; }
if(iPageNo < 1){      iPageNo = 1; }

// 把当前页号设置成请求参数
sb.append("<input type=\"hidden\" name=\"").append("pageNo")
.append("\" value=\"").append(pageNo).append("\"/>\r\n");

// 输出统计数据
sb.append("共 <strong>").append(recordCount)
.append("</strong> 项")
.append(", 共 <strong>")
.append(iPageCount)
.append("</strong> 页: \r\n");

//上一页处理
if (iPageNo == 1) {
sb.append("<span class=\"disabled\">« 上一页")
.append("</span>\r\n");
} else {
sb.append("<a href=\"javascript:turnOverPage(")
.append((iPageNo - 1))
.append(")\">« 上一页</a>\r\n");
}

//如果前面页数过多,显示"..."
int start = 1;
if(iPageNo > 4){
start = iPageNo - 1;
sb.append("<a href=\"javascript:turnOverPage(1)\">1</a>\r\n")
.append("<a href=\"javascript:turnOverPage(2)\">2</a>\r\n")
.append("…\r\n");
}
//显示当前页附近的页
int end = iPageNo + 1;
if(end > iPageCount){
end = iPageCount;
}
for(int i = start; i <= end; i++){
if(iPageNo == i){   //当前页号不需要超链接
sb.append("<span class=\"current\">")
.append(i)
.append("</span>\r\n");
}else{
sb.append("<a href=\"javascript:turnOverPage(")
.append(i)
.append(")\">")
.append(i)
.append("</a>\r\n");
}
}
//如果后面页数过多,显示"..."
if(end < iPageCount - 2){
sb.append("…\r\n");
}
if(end < iPageCount - 1){
sb.append("<a href=\"javascript:turnOverPage(")
.append(iPageCount - 1)
.append(")\">")
.append(iPageCount - 1)
.append("</a>\r\n");
}
if(end < iPageCount){
sb.append("<a href=\"javascript:turnOverPage(")
.append(iPageCount)
.append(")\">")
.append(iPageCount)
.append("</a>\r\n");
}

//下一页处理
if (iPageNo == iPageCount) {
sb.append("<span class=\"disabled\">下一页 »")
.append("</span>\r\n");
} else {
sb.append("<a href=\"javascript:turnOverPage(")
.append((iPageNo + 1))
.append(")\">下一页 »</a>\r\n");
}

if(bShowChangePageSize){
//每页记录数
sb.append("每页记录数:<select id=\"recordNum\" name=\"recordNum\" onChange=\"turnOverPage(" + pageNo + ")\">");
if(recordNum.equals("20")){
sb.append("<option value=\"20\" selected>20</option>");
}else{
sb.append("<option value=\"20\">20</option>");
}
if(recordNum.equals("50")){
sb.append("<option value=\"50\" selected>50</option>");
}else{
sb.append("<option value=\"50\">50</option>");
}
if(recordNum.equals("100")){
sb.append("<option value=\"100\" selected>100</option>");
}else{
sb.append("<option value=\"100\">100</option>");
}
if(recordNum.equals("150")){
sb.append("<option value=\"150\" selected>150</option>");
}else{
sb.append("<option value=\"150\">150</option>");
}
if(recordNum.equals("200")){
sb.append("<option value=\"200\" selected>200</option>");
}else{
sb.append("<option value=\"200\">200</option>");
}
sb.append("</select>");
}

if(bShowJumpPage){
//跳转页
sb.append(" 跳转到<input id=\"pageNum\" type=\"text\" name=\"pageNum\" size=\"2\" length=\"5\" ")
.append("onKeyPress=\"inputInt(event)\" ")
.append(">")
.append("<a href=\"javascript:jumpPage();")
.append("\">跳转 »</a>\r\n");
}

// 生成提交表单的JS
sb.append("<script language=\"javascript\">\r\n")
.append("  function turnOverPage(no){\r\n")
.append("    if(no>").append(iPageCount).append("){")
.append("      no=").append(iPageCount).append(";}\r\n")
.append("    if(no<1){no=1;}\r\n")
.append("    document.getElementById('" + formId + "').pageNo.value=no;\r\n")
.append("    document.getElementById('" + formId + "').submit();\r\n")
.append("  }\r\n")
.append(" function inputInt(event){\r\n")
.append("  var keyNum;\r\n")
.append("  var keyCode;\r\n")
.append("  if(window.event){\r\n")
.append("      keyNum=event.keyCode;\r\n")
.append("  }else if(event.which){\r\n")
.append("      keyNum=event.which;\r\n")
.append("  }\r\n")
.append("  if(keyNum<46 || keyNum>57){\r\n")
.append("    if(window.event){\r\n")
.append("       event.returnValue=false;\r\n")
.append("    }else{\r\n")
.append("       event.preventDefault();\r\n")
.append("    }\r\n")
.append("   }\r\n")
.append("	}\r\n")
.append("  function jumpPage(){\r\n")
.append("    var no=1;\r\n")
.append("    if(document.getElementsById('pageNum').value==''){\r\n")
.append("      alert('跳转页码必须填写!');\r\n")
.append("    }else{\r\n")
.append("      no=parseInt(document.getElementsById('pageNum').value);\r\n")
.append("    }\r\n")
.append("    turnOverPage(no);\r\n")
.append("  }\r\n")
.append("</script>\r\n");
}
sb.append("</div>\r\n");

writer.write(sb.toString());

} catch (IOException ex) {
ex.printStackTrace();
}
return result;
}
}


Pager.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>cb</short-name>
<uri>/citybug-tags</uri>
<display-name>"自定义分页标签"</display-name>

<tag>
<name>pager</name>
<tag-class>com.citybug.tag.PagerTag</tag-class>
<body-content>jsp</body-content>
<description>分页标签</description>
<attribute>
<name>pageNo</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>recordCount</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>pageSize</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>showChangePageSize</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>showJumpPage</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>formId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>


2.自定义标签的打包

自定义标签经过测试没有问题后,就要打包成JAR文件用到项目中去了,如何打包呢?方法比较简单:

建立一个空目录
到部署服务器下,把组成标签的java的class类复制到建立的目录中,当然,要保持class类的路径和tld中的类路径一致
把部署服务器下的“META_INF”复制到建立的目录中
把tld文件复制到META_INF目录中
选中目录中的全部文件,使用winrar压缩软件,把选中的文件制作成压缩包。压缩格式选择为“ZIP”,如果是“RAR”格式,项目运行时,会出现“打不开文件”的错误信息。然后将要锁文件后缀改为JAR即可。
把新建的JAR文件复制到项目的LIB目录下,就可以使用了。

3. 页面上如何使用

页面上使用和struts2自己的标签没有什么区别:

在页面的开头引用标签:

<%@ taglib prefix="cb"  uri="/citybug-tags" %>


这个自定义标签由于要达到和查询条件融合在一起,所以需要把标签和查询条件放置在同一个form中。

<cb:pager pageNo="page.pageNo" pageSize="page.pageSize" formId="form1" recordCount="page.recordCount" showChangePageSize="true" showJumpPage="true"/>
在上面的标签使用中,有page对象,这就是action中用于返回分页信息的对象。这个对象的代码非常简单,仅仅包含三个属性和这三个属性的getter和setter方法。代码如下:

Page.java

/**
* TODO
* Page.java
* Administrator2012-12-20
*/
package com.citybug.comm;

/**
* @author Administrator
*
*/
public class Page {
private int pageNo;
private int pageSize;
private int recordCount;

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 getRecordCount(){
return recordCount;
}

public void setRecordCount(int recordCount){
this.recordCount=recordCount;
}
}


那么在action中,需要一个通用方法,把page中的各个参数之间的逻辑关系表述清楚,我的代码如下:

private Page setPagePro(int recordCount){
Page page=null;
int pageCount;
int iPageNum;
try{
pageNo=this.getPageNo();
pageSize=this.getPageSize();
recordNum=this.getRecordNum();
pageNum=this.getPageNum();

if(pageSize==0){
pageSize=20;
}
if(pageNo==0){
pageNo=1;
}
if(recordNum!=0){
if(pageSize!=recordNum){
pageSize=recordNum;
}
}
if(pageNum!=null && !pageNum.equals("")){
iPageNum=Integer.valueOf(pageNum);
if(iPageNum>0){
if(pageNo!=iPageNum){
pageNo=iPageNum;
}
}
}

pageCount=(recordCount+pageSize-1)/pageSize;
if(pageNo>pageCount){
pageNo=pageCount;
}
page=new Page();
page.setPageNo(pageNo);
page.setPageSize(pageSize);
page.setRecordCount(recordCount);
}catch(Exception ex){
ex.printStackTrace();
}

return page;
}


为什么上面要这么写,是因为标签中可以改变每页的记录数和页码的跳转,每页记录数是以默认值为准,还是以页面上“每页记录数”下拉框中选择的数量为准?是以默认的页码为准还是以跳转中输入的页码为准?就是上面这个过程要解决的问题。其中的逻辑并不复杂。

那么接下来,只要把记录list和page对象返回给jsp页面,分页就成功了!

4。分页标签开发中的几个注意事项:

list如何传入标签?

在我们开发自定义标签时,可能会碰到要把一个list对象传给标签,然后由标签进行处理后,给出一个结果。但是struts2中却是把所有的参数认为是String。那么就会出现在自定义标签的java中要获得list对象时,就不知道如何才能获得这个list。在参照struts2的core中源码情况下,有了下面的解决办法:

在继承自“ComponentTagSupport”的类中,把list的变量类型设置为Object。

private Object list;


在继承自“Component”的类中,在方法“end(Writer writer,String body)”中获取list的对象时,用下面的语句进行转换:

obj=this.getStack().findValue((String)list);
ArrayList<?> beanList = (ArrayList<?>)obj;

这样,就可以获得list的队列内容。至于如何使用,可以使用反射,也可以对队列进行类型转换等等,这就要看具体的需要了。

在标签中,传入的是字符串或者具体的值,而不是变量时,如何获取到值?

看完上面的自定义标签,在end过程中,看到取值使用的是 Object obj=this.getStack().findValue(pageNo); 的方法。那么就会形成一种思维定势,认为获取标签传入的值都是采用这样的方式获取值。但是并不是如此,这是因为JSP页面上是这么写的 pageNo=”page.pageNo".那么,如果是直接写成 pageNo=“1”,就不用再使用findValue这个方法了,而是直接使用pageNo变量即可。这本不是个问题,只是在此给提个醒.


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: