在Struts2中实现自定义分页标签

我们先看看这个分页标签的效果:

使用标签的最大好处就是下次再用到的话直接引用就行,而不必重写。

本人对Struts2自定义标签没有太深究,在网上找了一些资料可以参考参考:

其实,开发自定义标签并不需要Struts2的支持,一般情况下,只需要继承javax.servlet.jsp.tagext.BodyTagSupport类,重写doStartTag,doEndTag等方法即可。这里在实现自定义标签时,继承的2个类分别是org.apache.struts2.views.jsp.ComponentTagSupport和org.apache.struts2.components.Component,ComponentTagSupport实际上是对BodyTagSupport的一次封装,看一下ComponentTagSupport类的继承关系就明了了:

 

  1. <em>java.lang.Object    
  2.   extended by javax.servlet.jsp.tagext.TagSupport    
  3.       extended by javax.servlet.jsp.tagext.BodyTagSupport    
  4.           extended by org.apache.struts2.views.jsp.StrutsBodyTagSupport    
  5.               extended by org.apache.struts2.views.jsp.ComponentTagSupport</em>  

继承ComponentTagSupport类是为了获得标签中的属性值,并包装成Component对象。继承Component类是为了从Struts2中的ValueStack中获得相对应的值。
下面开始写我们的自定义分页标签,

 

Struts2要实现自定义标签的话,其实很简单,只需三个步骤就能实现:

第一步:创建tld文件。

tld文件其实就相当与一个标准的XML文件,其中包含了对自定义标签的声明(标签名,对应类全限定名,标签主题类型,标签属性等),在jsp中引入该标签时,web服务器会对对应的全限定名类进行实例化,和Struts的配置文件极为相似,代码如下:

pager.tld

 

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">  
  5.     <tlib-version>5.0</tlib-version>  
  6.     <short-name>myTag</short-name>  
  7.     <uri>http://hi.csdn.net/tjcyjd/tags</uri>  
  8.     <!-- 自定义标签的描述信息 -->  
  9.     <tag>  
  10.         <!-- 标签名 -->  
  11.         <name>pager</name>  
  12.         <!-- 对应的标签处理类全限定名 -->  
  13.         <tag-class>com.yjd.web.tags.PagerTag</tag-class>  
  14.         <!-- 标签主体的类型 -->  
  15.         <body-content>empty</body-content>  
  16.         <!-- 当前页号属性的描述信息 -->  
  17.         <attribute>  
  18.             <!-- 属性名 -->  
  19.             <name>pageNo</name>  
  20.             <!-- 该属性是否为必要的 -->  
  21.             <required>true</required>  
  22.             <!-- 属性值是否可以在JSP运行时期动态产生 -->  
  23.             <rtexprvalue>true</rtexprvalue>  
  24.             <!-- 属性的数据类型 -->  
  25.             <type>int</type>  
  26.         </attribute>  
  27.         <!-- 总记录数属性的描述信息 -->  
  28.         <attribute>  
  29.             <name>recordCount</name>  
  30.             <required>true</required>  
  31.             <rtexprvalue>true</rtexprvalue>  
  32.             <type>int</type>  
  33.         </attribute>  
  34.         <!-- 总页数属性的描述信息 -->  
  35.         <attribute>  
  36.             <name>pageSize</name>  
  37.             <required>true</required>  
  38.             <rtexprvalue>true</rtexprvalue>  
  39.             <type>int</type>  
  40.         </attribute>  
  41.         <!-- 分页标签要跳转的URI属性的描述信息 -->  
  42.         <attribute>  
  43.             <name>url</name>  
  44.             <required>true</required>  
  45.             <rtexprvalue>true</rtexprvalue>  
  46.             <type>java.lang.String</type>  
  47.         </attribute>  
  48.     </tag>  
  49. </taglib>  

 

第二步:编写自定义标签类,注意要和对应的标签处理类全限定名一致,代码如下:

PagerTag.java

 

  1. package com.yjd.web.tags;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.Enumeration;  
  5.   
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.jsp.JspException;  
  8. import javax.servlet.jsp.tagext.TagSupport;  
  9.   
  10. public class PagerTag extends TagSupport {  
  11.     private static final long serialVersionUID = 5729832874890369508L;  
  12.     private String url;  
  13.     private int pageSize = 10;  
  14.     private int pageNo = 1;  
  15.     private int recordCount;  
  16.   
  17.     public int doStartTag() throws JspException {  
  18.         int pageCount = (this.recordCount + this.pageSize - 1) / this.pageSize;  
  19.   
  20.         StringBuilder sb = new StringBuilder();  
  21.   
  22.         sb.append("<style type=\"text/css\">");  
  23.         sb.append(".pagination {padding: 5px;float:right;font-size:12px;}");  
  24.         sb  
  25.                 .append(".pagination a, .pagination a:link, .pagination a:visited {padding:2px 5px;margin:2px;border:1px solid #aaaadd;text-decoration:none;color:#006699;}");  
  26.         sb  
  27.                 .append(".pagination a:hover, .pagination a:active {border: 1px solid #ff0000;color: #000;text-decoration: none;}");  
  28.         sb  
  29.                 .append(".pagination span.current {padding: 2px 5px;margin: 2px;border: 1px solid #ff0000;font-weight: bold;background-color: #ff0000;color: #FFF;}");  
  30.         sb  
  31.                 .append(".pagination span.disabled {padding: 2px 5px;margin: 2px;border: 1px solid #eee; color: #ddd;}");  
  32.         sb.append("</style>\r\n");  
  33.         sb.append("<div class=\"pagination\">\r\n");  
  34.         if (this.recordCount == 0) {  
  35.             sb.append("<strong>没有可显示的项目</strong>\r\n");  
  36.         } else {  
  37.             if (this.pageNo > pageCount)  
  38.                 this.pageNo = pageCount;  
  39.             if (this.pageNo < 1)  
  40.                 this.pageNo = 1;  
  41.   
  42.             sb.append("<form method=\"post\" action=\"").append(this.url)  
  43.                     .append("\" name=\"qPagerForm\">\r\n");  
  44.   
  45.             HttpServletRequest request = (HttpServletRequest) this.pageContext  
  46.                     .getRequest();  
  47.             Enumeration enumeration = request.getParameterNames();  
  48.             String name = null;  
  49.             String value = null;  
  50.   
  51.             while (enumeration.hasMoreElements()) {  
  52.                 name = (String) enumeration.nextElement();  
  53.                 value = request.getParameter(name);  
  54.   
  55.                 if (name.equals("pageNo")) {  
  56.                     if ((value != null) && (!"".equals(value))) {  
  57.                         this.pageNo = Integer.parseInt(value);  
  58.                     }  
  59.                 } else {  
  60.                     sb.append("<input type=\"hidden\" name=\"").append(name)  
  61.                             .append("\" value=\"").append(value).append(  
  62.                                     "\"/>\r\n");  
  63.                 }  
  64.             }  
  65.   
  66.             sb.append("<input type=\"hidden\" name=\"").append("pageNo")  
  67.                     .append("\" value=\"").append(this.pageNo).append(  
  68.                             "\"/>\r\n");  
  69.   
  70.             sb.append(" 共<strong>").append(this.recordCount).append(  
  71.                     "</strong>项").append(",<strong>").append(pageCount).append(  
  72.                     "</strong>页: \r\n");  
  73.   
  74.             if (this.pageNo == 1)  
  75.                 sb.append("<span class=\"disabled\">« 上一页").append(  
  76.                         "</span>\r\n");  
  77.             else {  
  78.                 sb.append("<a href=\"javascript:turnOverPage(").append(  
  79.                         this.pageNo - 1).append(")\">« 上一页</a>\r\n");  
  80.             }  
  81.   
  82.             int start = 1;  
  83.             if (this.pageNo > 4) {  
  84.                 start = this.pageNo - 1;  
  85.                 sb.append("<a href=\"javascript:turnOverPage(1)\">1</a>\r\n");  
  86.                 sb.append("<a href=\"javascript:turnOverPage(2)\">2</a>\r\n");  
  87.                 sb.append("…\r\n");  
  88.             }  
  89.   
  90.             int end = this.pageNo + 1;  
  91.             if (end > pageCount) {  
  92.                 end = pageCount;  
  93.             }  
  94.             for (int i = start; i <= end; i++) {  
  95.                 if (this.pageNo == i)  
  96.                     sb.append("<span class=\"current\">").append(i).append(  
  97.                             "</span>\r\n");  
  98.                 else {  
  99.                     sb.append("<a href=\"javascript:turnOverPage(").append(i)  
  100.                             .append(")\">").append(i).append("</a>\r\n");  
  101.                 }  
  102.             }  
  103.   
  104.             if (end < pageCount - 2) {  
  105.                 sb.append("…\r\n");  
  106.             }  
  107.             if (end < pageCount - 1) {  
  108.                 sb.append("<a href=\"javascript:turnOverPage(").append(  
  109.                         pageCount - 1).append(")\">").append(pageCount - 1)  
  110.                         .append("</a>\r\n");  
  111.             }  
  112.             if (end < pageCount) {  
  113.                 sb.append("<a href=\"javascript:turnOverPage(").append(  
  114.                         pageCount).append(")\">").append(pageCount).append(  
  115.                         "</a>\r\n");  
  116.             }  
  117.   
  118.             if (this.pageNo == pageCount)  
  119.                 sb.append("<span class=\"disabled\">下一页 »").append(  
  120.                         "</span>\r\n");  
  121.             else {  
  122.                 sb.append("<a href=\"javascript:turnOverPage(").append(  
  123.                         this.pageNo + 1).append(")\">下一页 »</a>\r\n");  
  124.             }  
  125.             sb.append("</form>\r\n");  
  126.   
  127.             sb.append("<script language=\"javascript\">\r\n");  
  128.             sb.append("  function turnOverPage(no){\r\n");  
  129.             sb.append("    if(no>").append(pageCount).append("){");  
  130.             sb.append("      no=").append(pageCount).append(";}\r\n");  
  131.             sb.append("    if(no<1){no=1;}\r\n");  
  132.             sb.append("    document.qPagerForm.pageNo.value=no;\r\n");  
  133.             sb.append("    document.qPagerForm.submit();\r\n");  
  134.             sb.append("  }\r\n");  
  135.             sb.append("</script>\r\n");  
  136.         }  
  137.         sb.append("</div>\r\n");  
  138.         try {  
  139.             this.pageContext.getOut().println(sb.toString());  
  140.         } catch (IOException e) {  
  141.             throw new JspException(e);  
  142.         }  
  143.         return 0;  
  144.     }  
  145.   
  146.     public void setUrl(String url) {  
  147.         this.url = url;  
  148.     }  
  149.   
  150.     public void setPageSize(int pageSize) {  
  151.         this.pageSize = pageSize;  
  152.     }  
  153.   
  154.     public void setPageNo(int pageNo) {  
  155.         this.pageNo = pageNo;  
  156.     }  
  157.   
  158.     public void setRecordCount(int recordCount) {  
  159.         this.recordCount = recordCount;  
  160.     }  
  161. }  

 

第三步:在jsp页面中直接引入该标签,其实和普通的c标签时一样的,代码如下(看第4句和第91句):

myTag.jsp

 

  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
  3. <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>  
  4. <%@taglib uri="http://hi.csdn.net/tjcyjd/tags" prefix="myTag" %>  
  5. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  6. <html><head><title>在线留言系统</title>  
  7. <meta http-equiv=content-type content="text/html; charset=UTF-8">  
  8. <link href="images/style.css" type=text/css rel=stylesheet></link>  
  9. <style type="text/css">  
  10. body{font-size: 12px}  
  11. table{font-size: 12px}  
  12. a{font-size:12px}  
  13. .current{font-size:12px;}  
  14. </style>  
  15.   
  16. </head>  
  17. <body><!--留言表单 -->  
  18. <form name=form1 action="msg/add.action" method=post>  
  19. <table class=tab cellspacing=1 align=center border=0>  
  20.   <tbody>  
  21.   <tr>  
  22.     <td class=title background=images/titlebg.jpg colspan=2   
  23.       height=25><span>请 签 写 留 言</span> </td></tr>  
  24.   <tr>  
  25.     <td align=right width="20%">您的称呼: </td>  
  26.     <td width="80%"><input id="username" maxlength=50 name="msg.nickname"/> </td></tr>  
  27.   <tr>  
  28.     <td align=right width="20%">您的性别: </td>  
  29.     <td width="80%"><input id=sex type=radio value="true" name="msg.gender">   
  30.       男    <input type=radio checked value="false" name="msg.gender"> 女   
  31.   </td></tr>  
  32.   <tr>  
  33.     <td align=right>选择头像: </td>  
  34.     <td><select id=image name="msg.header_img"> <option   
  35.         value=1.gif selected>1.gif</option> <option   
  36.         value=2.gif>2.gif</option> <option   
  37.         value=3.gif>3.gif</option> <option   
  38.         value=4.gif>4.gif</option> <option   
  39.         value=5.gif>5.gif</option> <option   
  40.         value=6.gif>6.gif</option> <option   
  41.         value=7.gif>7.gif</option> <option   
  42.         value=8.gif>8.gif</option> <option   
  43.         value=9.gif>9.gif</option> <option   
  44.         value=10.gif>10.gif</option> <option   
  45.         value=11.gif>11.gif</option> <option   
  46.         value=12.gif>12.gif</option> <option   
  47.         value=13.gif>13.gif</option> <option   
  48.         value=14.gif>14.gif</option> <option   
  49.         value=15.gif>15.gif</option> <option   
  50.         value=16.gif>16.gif</option> <option   
  51.         value=17.gif>17.gif</option> <option   
  52.         value=18.gif>18.gif</option> <option   
  53.         value=19.gif>19.gif</option> <option   
  54.         value=20.gif>20.gif</option></select> </td></tr>  
  55.   <tr>  
  56.     <td align=right>您的qq: </td>  
  57.     <td><input id=qq maxlength=50 name="msg.qq"> </td></tr>  
  58.   <tr>  
  59.     <td align=right>您的邮箱: </td>  
  60.     <td><input id=email maxlength=50 name="msg.email"> </td></tr>  
  61.   <tr>  
  62.     <td align=right>留言内容: </td>  
  63.     <td><textarea id=content name="msg.content" rows=5 cols=50></textarea>   
  64.   </td></tr>  
  65.   <tr>  
  66.     <td align="center" colspan=2><input type=submit value=提交>       
  67. <input type=reset value=重置> </td></tr></tbody></table></form><!--留言表单结束 --><!--留言列表 -->  
  68. <table class=tab cellspacing=1 align=center border=0>  
  69.   <tbody>  
  70.   <tr>  
  71.     <td class=title background=images/titlebg.jpg colspan=2   
  72.       height=25><span>留 言 列 表【<a href="login.jsp">管理登录</a>】 </span></td></tr>  
  73.   
  74. <c:forEach items="${pm.data}" var="msg">  
  75.   <tr>  
  76.     <td align="center" width="20%" rowspan=4>你好 : ${msg.nickname} ${msg.gender ? "帅哥" : "靓妹"} <br><br><img   
  77.       src="images/${msg.header_img}"> </td></tr>  
  78.   <tr>  
  79.     <td width="80%" height="100%">发表于: <fmt:formatDate value="${msg.pubTime}" pattern="yyyy-MM-dd HH:mm:ss"/>   <img   
  80.       src="images/8_online.gif" border=0> <a href="mailto:${msg.email}"><img   
  81.       src="images/email.gif" border=0></a> <img src="images/ip.gif"   
  82.       border=0> 来自:${msg.ip}</td></tr>  
  83.   <tr>  
  84.     <td>${msg.content}</td></tr>  
  85.   <tr>  
  86.     <td><font color=#ff0000>管理员回复:</font> </td></tr>  
  87. </c:forEach>  
  88.    
  89. </tbody></table><!--留言列表显示结束-->  
  90.     <!--一引入分页标签 -->  
  91.     <myTag:pager pageSize="${pm.pageSize}" pageNo="${pm.pageNo}" url="index.action" recordCount="${pm.recordCount}"/>  
  92.     <!--分页标签结束 -->  
  93. </body></html>  


通过上面的步骤我们发现,其实自定义一个标签也不是很复杂的事……

 

原文出处:http://blog.csdn.net/tjcyjd/article/details/6844124

posted @ 2013-01-18 18:08  Chendisheng  阅读(677)  评论(0编辑  收藏  举报