1. 程式人生 > >在Struts2中實現自定義分頁標籤全攻略(一)

在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類的繼承關係就明瞭了:


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
繼承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>

通過上面的步驟我們發現,其實自定義一個標籤也不是很複雜的事……