在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类的继承关系就明了了:
- <em>java.lang.Object
- extended by javax.servlet.jsp.tagext.TagSupport
- extended by javax.servlet.jsp.tagext.BodyTagSupport
- extended by org.apache.struts2.views.jsp.StrutsBodyTagSupport
- extended by org.apache.struts2.views.jsp.ComponentTagSupport</em>
继承ComponentTagSupport类是为了获得标签中的属性值,并包装成Component对象。继承Component类是为了从Struts2中的ValueStack中获得相对应的值。
下面开始写我们的自定义分页标签,
Struts2要实现自定义标签的话,其实很简单,只需三个步骤就能实现:
第一步:创建tld文件。
tld文件其实就相当与一个标准的XML文件,其中包含了对自定义标签的声明(标签名,对应类全限定名,标签主题类型,标签属性等),在jsp中引入该标签时,web服务器会对对应的全限定名类进行实例化,和Struts的配置文件极为相似,代码如下:
pager.tld
- <?xml version="1.0" encoding="UTF-8"?>
- <taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
- <tlib-version>5.0</tlib-version>
- <short-name>myTag</short-name>
- <uri>http://hi.csdn.net/tjcyjd/tags</uri>
- <!-- 自定义标签的描述信息 -->
- <tag>
- <!-- 标签名 -->
- <name>pager</name>
- <!-- 对应的标签处理类全限定名 -->
- <tag-class>com.yjd.web.tags.PagerTag</tag-class>
- <!-- 标签主体的类型 -->
- <body-content>empty</body-content>
- <!-- 当前页号属性的描述信息 -->
- <attribute>
- <!-- 属性名 -->
- <name>pageNo</name>
- <!-- 该属性是否为必要的 -->
- <required>true</required>
- <!-- 属性值是否可以在JSP运行时期动态产生 -->
- <rtexprvalue>true</rtexprvalue>
- <!-- 属性的数据类型 -->
- <type>int</type>
- </attribute>
- <!-- 总记录数属性的描述信息 -->
- <attribute>
- <name>recordCount</name>
- <required>true</required>
- <rtexprvalue>true</rtexprvalue>
- <type>int</type>
- </attribute>
- <!-- 总页数属性的描述信息 -->
- <attribute>
- <name>pageSize</name>
- <required>true</required>
- <rtexprvalue>true</rtexprvalue>
- <type>int</type>
- </attribute>
- <!-- 分页标签要跳转的URI属性的描述信息 -->
- <attribute>
- <name>url</name>
- <required>true</required>
- <rtexprvalue>true</rtexprvalue>
- <type>java.lang.String</type>
- </attribute>
- </tag>
- </taglib>
第二步:编写自定义标签类,注意要和对应的标签处理类全限定名一致,代码如下:
PagerTag.java
- package com.yjd.web.tags;
- import java.io.IOException;
- import java.util.Enumeration;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.jsp.JspException;
- import javax.servlet.jsp.tagext.TagSupport;
- public class PagerTag extends TagSupport {
- private static final long serialVersionUID = 5729832874890369508L;
- private String url;
- private int pageSize = 10;
- private int pageNo = 1;
- private int recordCount;
- public int doStartTag() throws JspException {
- int pageCount = (this.recordCount + this.pageSize - 1) / this.pageSize;
- StringBuilder sb = new StringBuilder();
- sb.append("<style type=\"text/css\">");
- sb.append(".pagination {padding: 5px;float:right;font-size:12px;}");
- 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 (this.recordCount == 0) {
- sb.append("<strong>没有可显示的项目</strong>\r\n");
- } else {
- if (this.pageNo > pageCount)
- this.pageNo = pageCount;
- if (this.pageNo < 1)
- this.pageNo = 1;
- sb.append("<form method=\"post\" action=\"").append(this.url)
- .append("\" name=\"qPagerForm\">\r\n");
- HttpServletRequest request = (HttpServletRequest) this.pageContext
- .getRequest();
- Enumeration enumeration = request.getParameterNames();
- String name = null;
- String value = null;
- while (enumeration.hasMoreElements()) {
- name = (String) enumeration.nextElement();
- value = request.getParameter(name);
- if (name.equals("pageNo")) {
- if ((value != null) && (!"".equals(value))) {
- this.pageNo = Integer.parseInt(value);
- }
- } else {
- sb.append("<input type=\"hidden\" name=\"").append(name)
- .append("\" value=\"").append(value).append(
- "\"/>\r\n");
- }
- }
- sb.append("<input type=\"hidden\" name=\"").append("pageNo")
- .append("\" value=\"").append(this.pageNo).append(
- "\"/>\r\n");
- sb.append(" 共<strong>").append(this.recordCount).append(
- "</strong>项").append(",<strong>").append(pageCount).append(
- "</strong>页: \r\n");
- if (this.pageNo == 1)
- sb.append("<span class=\"disabled\">« 上一页").append(
- "</span>\r\n");
- else {
- sb.append("<a href=\"javascript:turnOverPage(").append(
- this.pageNo - 1).append(")\">« 上一页</a>\r\n");
- }
- int start = 1;
- if (this.pageNo > 4) {
- start = this.pageNo - 1;
- sb.append("<a href=\"javascript:turnOverPage(1)\">1</a>\r\n");
- sb.append("<a href=\"javascript:turnOverPage(2)\">2</a>\r\n");
- sb.append("…\r\n");
- }
- int end = this.pageNo + 1;
- if (end > pageCount) {
- end = pageCount;
- }
- for (int i = start; i <= end; i++) {
- if (this.pageNo == 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 < pageCount - 2) {
- sb.append("…\r\n");
- }
- if (end < pageCount - 1) {
- sb.append("<a href=\"javascript:turnOverPage(").append(
- pageCount - 1).append(")\">").append(pageCount - 1)
- .append("</a>\r\n");
- }
- if (end < pageCount) {
- sb.append("<a href=\"javascript:turnOverPage(").append(
- pageCount).append(")\">").append(pageCount).append(
- "</a>\r\n");
- }
- if (this.pageNo == pageCount)
- sb.append("<span class=\"disabled\">下一页 »").append(
- "</span>\r\n");
- else {
- sb.append("<a href=\"javascript:turnOverPage(").append(
- this.pageNo + 1).append(")\">下一页 »</a>\r\n");
- }
- sb.append("</form>\r\n");
- sb.append("<script language=\"javascript\">\r\n");
- sb.append(" function turnOverPage(no){\r\n");
- sb.append(" if(no>").append(pageCount).append("){");
- sb.append(" no=").append(pageCount).append(";}\r\n");
- sb.append(" if(no<1){no=1;}\r\n");
- sb.append(" document.qPagerForm.pageNo.value=no;\r\n");
- sb.append(" document.qPagerForm.submit();\r\n");
- sb.append(" }\r\n");
- sb.append("</script>\r\n");
- }
- sb.append("</div>\r\n");
- try {
- this.pageContext.getOut().println(sb.toString());
- } catch (IOException e) {
- throw new JspException(e);
- }
- return 0;
- }
- public void setUrl(String url) {
- this.url = url;
- }
- public void setPageSize(int pageSize) {
- this.pageSize = pageSize;
- }
- public void setPageNo(int pageNo) {
- this.pageNo = pageNo;
- }
- public void setRecordCount(int recordCount) {
- this.recordCount = recordCount;
- }
- }
第三步:在jsp页面中直接引入该标签,其实和普通的c标签时一样的,代码如下(看第4句和第91句):
myTag.jsp
- <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
- <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
- <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
- <%@taglib uri="http://hi.csdn.net/tjcyjd/tags" prefix="myTag" %>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html><head><title>在线留言系统</title>
- <meta http-equiv=content-type content="text/html; charset=UTF-8">
- <link href="images/style.css" type=text/css rel=stylesheet></link>
- <style type="text/css">
- body{font-size: 12px}
- table{font-size: 12px}
- a{font-size:12px}
- .current{font-size:12px;}
- </style>
- </head>
- <body><!--留言表单 -->
- <form name=form1 action="msg/add.action" method=post>
- <table class=tab cellspacing=1 align=center border=0>
- <tbody>
- <tr>
- <td class=title background=images/titlebg.jpg colspan=2
- height=25><span>请 签 写 留 言</span> </td></tr>
- <tr>
- <td align=right width="20%">您的称呼: </td>
- <td width="80%"><input id="username" maxlength=50 name="msg.nickname"/> </td></tr>
- <tr>
- <td align=right width="20%">您的性别: </td>
- <td width="80%"><input id=sex type=radio value="true" name="msg.gender">
- 男 <input type=radio checked value="false" name="msg.gender"> 女
- </td></tr>
- <tr>
- <td align=right>选择头像: </td>
- <td><select id=image name="msg.header_img"> <option
- value=1.gif selected>1.gif</option> <option
- value=2.gif>2.gif</option> <option
- value=3.gif>3.gif</option> <option
- value=4.gif>4.gif</option> <option
- value=5.gif>5.gif</option> <option
- value=6.gif>6.gif</option> <option
- value=7.gif>7.gif</option> <option
- value=8.gif>8.gif</option> <option
- value=9.gif>9.gif</option> <option
- value=10.gif>10.gif</option> <option
- value=11.gif>11.gif</option> <option
- value=12.gif>12.gif</option> <option
- value=13.gif>13.gif</option> <option
- value=14.gif>14.gif</option> <option
- value=15.gif>15.gif</option> <option
- value=16.gif>16.gif</option> <option
- value=17.gif>17.gif</option> <option
- value=18.gif>18.gif</option> <option
- value=19.gif>19.gif</option> <option
- value=20.gif>20.gif</option></select> </td></tr>
- <tr>
- <td align=right>您的qq: </td>
- <td><input id=qq maxlength=50 name="msg.qq"> </td></tr>
- <tr>
- <td align=right>您的邮箱: </td>
- <td><input id=email maxlength=50 name="msg.email"> </td></tr>
- <tr>
- <td align=right>留言内容: </td>
- <td><textarea id=content name="msg.content" rows=5 cols=50></textarea>
- </td></tr>
- <tr>
- <td align="center" colspan=2><input type=submit value=提交>
- <input type=reset value=重置> </td></tr></tbody></table></form><!--留言表单结束 --><!--留言列表 -->
- <table class=tab cellspacing=1 align=center border=0>
- <tbody>
- <tr>
- <td class=title background=images/titlebg.jpg colspan=2
- height=25><span>留 言 列 表【<a href="login.jsp">管理登录</a>】 </span></td></tr>
- <c:forEach items="${pm.data}" var="msg">
- <tr>
- <td align="center" width="20%" rowspan=4>你好 : ${msg.nickname} ${msg.gender ? "帅哥" : "靓妹"} <br><br><img
- src="images/${msg.header_img}"> </td></tr>
- <tr>
- <td width="80%" height="100%">发表于: <fmt:formatDate value="${msg.pubTime}" pattern="yyyy-MM-dd HH:mm:ss"/> <img
- src="images/8_online.gif" border=0> <a href="mailto:${msg.email}"><img
- src="images/email.gif" border=0></a> <img src="images/ip.gif"
- border=0> 来自:${msg.ip}</td></tr>
- <tr>
- <td>${msg.content}</td></tr>
- <tr>
- <td><font color=#ff0000>管理员回复:</font> </td></tr>
- </c:forEach>
- </tbody></table><!--留言列表显示结束-->
- <!--一引入分页标签 -->
- <myTag:pager pageSize="${pm.pageSize}" pageNo="${pm.pageNo}" url="index.action" recordCount="${pm.recordCount}"/>
- <!--分页标签结束 -->
- </body></html>
通过上面的步骤我们发现,其实自定义一个标签也不是很复杂的事……