Struts2中实现自定义分页标签

本文介绍如何在Struts2框架中实现自定义分页标签,包括创建.tld文件声明标签、编写标签类及组件类、配置Action以及在JSP页面中使用自定义标签的过程。

    Struts2中实现自定义标签很简单,主要分为3步:

    1.创建taglib文件(.tld),编写标签声明。

    2.编写自定义标签类。

    3.在页面中使用标签。

    下面以一个自定义的分页标签为例,进行说明。

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

   1. 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 

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中获得相对应的值。

1.声明自定义标签。

首先,需要创建一个tld文件,这是一个标准的XML文件,这个文件中就包含有对自定义标签的声明,声明指出了标签的名字,实现标签的类,标签的属性等信息。当在页面中使用该标签时,web服务器就会从这个文件中找出相对应的标签类,并实例化后执行。这个文件其实与struts.xml文件的作用相类似。

tangs.tld
Xml代码

   1. <?xml version="1.0" encoding="UTF-8"?> 
   2. <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> 
   3. <taglib> 
   4.     <tlib-version>2.2.3</tlib-version> 
   5.     <jsp-version>1.2</jsp-version> 
   6.     <short-name>tangs</short-name> 
   7.     <uri>/tangs</uri> 
   8.     <display-name>"Tangs Tags"</display-name> 
   9.      
  10.         <tag> 
  11.             <name>pages</name> 
  12.             <tag-class>com.tangs.tag.PageTag</tag-class>   //标签类 
  13.             <body-content>empty</body-content> 
  14.             <attribute>   //标签中的属性 
  15.                 <name>cpage</name>  //属性名 
  16.                 <required>true</required>  //是否必须 
  17.                 <rtexprvalue>true</rtexprvalue>  // 表示该自定义标签的某属性的值可以直接指定或者通过动态计算指定 
  18.             </attribute> 
  19.             <attribute> 
  20.                 <name>total</name> 
  21.                 <required>true</required> 
  22.                 <rtexprvalue>true</rtexprvalue> 
  23.             </attribute> 
  24.             <attribute> 
  25.                 <name>url</name> 
  26.                 <required>true</required> 
  27.                 <rtexprvalue>true</rtexprvalue> 
  28.             </attribute> 
  29.         </tag> 
  30. </taglib> 

<?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>2.2.3</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>tangs</short-name>
    <uri>/tangs</uri>
    <display-name>"Tangs Tags"</display-name>
   
        <tag>
            <name>pages</name>
            <tag-class>com.tangs.tag.PageTag</tag-class>   //标签类
            <body-content>empty</body-content>
            <attribute>   //标签中的属性
                <name>cpage</name>  //属性名
                <required>true</required>  //是否必须
                <rtexprvalue>true</rtexprvalue>  //表示该自定义标签的某属性的值可以直接指定或者通过动态计算指定
            </attribute>
            <attribute>
                <name>total</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
            <attribute>
                <name>url</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
        </tag>
</taglib>

 2.编写标签类

PageTag.java
Java代码

   1. package com.tangs.tag; 
   2.  
   3. import com.opensymphony.xwork2.util.ValueStack; 
   4. import javax.servlet.http.HttpServletRequest; 
   5. import javax.servlet.http.HttpServletResponse; 
   6. import org.apache.struts2.components.Component; 
   7. import org.apache.struts2.views.jsp.ComponentTagSupport; 
   8.  
   9. /**
  10.  * 分页标签
  11.  * @author tangs
  12.  */ 
  13. public class PageTag extends ComponentTagSupport { 
  14.     private String cpage;  //当前页 
  15.     private String total;  //总页数 
  16.     private String url;  //请求地址 
  17.  
  18.     public void setCpage(String cpage) { 
  19.         this.cpage = cpage; 
  20.     } 
  21.  
  22.     public void setTotal(String total) { 
  23.         this.total = total; 
  24.     } 
  25.  
  26.     public void setUrl(String url) { 
  27.         this.url = url; 
  28.     } 
  29.  
  30.     @Override 
  31.     public Component getBean(ValueStack arg0, HttpServletRequest arg1, HttpServletResponse arg2) { 
  32.         return new Pages(arg0); //返回Pages Component,分页的逻辑处理都在这个Component中 
  33.     } 
  34.  
  35.     //获得参数 
  36.     protected void populateParams() { 
  37.         super.populateParams(); 
  38.          
  39.         Pages pages = (Pages)component; 
  40.         pages.setCpage(cpage); 
  41.         pages.setTotal(total); 
  42.         pages.setUrl(url); 
  43.     } 
  44. } 

package com.tangs.tag;

import com.opensymphony.xwork2.util.ValueStack;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport;

/**
 * 分页标签
 * @author tangs
 */
public class PageTag extends ComponentTagSupport {
    private String cpage;  //当前页
    private String total;  //总页数
    private String url;  //请求地址

    public void setCpage(String cpage) {
        this.cpage = cpage;
    }

    public void setTotal(String total) {
        this.total = total;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @Override
    public Component getBean(ValueStack arg0, HttpServletRequest arg1, HttpServletResponse arg2) {
        return new Pages(arg0); //返回Pages Component,分页的逻辑处理都在这个Component中
    }

    //获得参数
    protected void populateParams() {
        super.populateParams();
       
        Pages pages = (Pages)component;
        pages.setCpage(cpage);
        pages.setTotal(total);
        pages.setUrl(url);
    }
}

    Pages.java
Java代码

   1. package com.tangs.tag; 
   2.  
   3. import com.opensymphony.xwork2.util.ValueStack; 
   4. import java.io.IOException; 
   5. import java.io.Writer; 
   6. import java.util.logging.Level; 
   7. import java.util.logging.Logger; 
   8. import org.apache.struts2.components.Component; 
   9.  
  10. /**
  11.  * 分页逻辑Bean
  12.  * @author tangs
  13.  */ 
  14. public class Pages extends Component { 
  15.     private String cpage; 
  16.     private String total; 
  17.     private String url; 
  18.  
  19.     public String getCpage() { 
  20.         return cpage; 
  21.     } 
  22.  
  23.     public void setCpage(String cpage) { 
  24.         this.cpage = cpage; 
  25.     } 
  26.  
  27.     public String getTotal() { 
  28.         return total; 
  29.     } 
  30.  
  31.     public void setTotal(String total) { 
  32.         this.total = total; 
  33.     } 
  34.  
  35.     public String getUrl() { 
  36.         return url; 
  37.     } 
  38.  
  39.     public void setUrl(String url) { 
  40.         this.url = url; 
  41.     } 
  42.      
  43.      
  44.     public Pages(ValueStack arg0) { 
  45.         super(arg0); 
  46.     } 
  47.  
  48.     @Override 
  49.     public boolean start(Writer writer) { 
  50.         boolean result = super.start(writer); 
  51.         try { 
  52.             StringBuilder str = new StringBuilder(); 
  53.             boolean isValid = true; 
  54.              
  55.             //从ValueStack中取出数值 
  56.             if (isValid) { 
  57.                 if (total.startsWith("%{") && total.endsWith("}")) { 
  58.                     total = total.substring(2, total.length() -1); 
  59.                     total = (String)this.getStack().findValue(total); 
  60.                     isValid = total == null ? false : true; 
  61.                 } else { 
  62.                     isValid = false; 
  63.                 } 
  64.             } 
  65.             if (isValid) { 
  66.                 if (cpage.startsWith("%{") && cpage.endsWith("}")) { 
  67.                     cpage = cpage.substring(2, cpage.length() - 1); 
  68.                     cpage = (String)this.getStack().findValue(cpage); 
  69.                     isValid = cpage == null ? false : true; 
  70.                 } else { 
  71.                     isValid = false; 
  72.                 } 
  73.             } 
  74.             if (isValid) { 
  75.                 if (url.startsWith("%{") && url.endsWith("}")) { 
  76.                     url = url.substring(2, url.length() - 1); 
  77.                     url = (String)this.getStack().findValue(url); 
  78.                     isValid = url == null ? false : true; 
  79.                 } else { 
  80.                     isValid = false; 
  81.                 } 
  82.             } 
  83.  
  84.             if (isValid) { 
  85.                 Integer cpageInt = Integer.valueOf(cpage); 
  86.                 //当前页与总页数相等 
  87.                 if (cpage.equals(total)) { 
  88.                     //如果total = 1,则无需分页,显示“[第1页] [共1页]” 
  89.                     if ("1".equals(total)) { 
  90.                         str.append("[第 " + cpage + " 页]"); 
  91.                         str.append(" [共 " + total + " 页]"); 
  92.                     } else { 
  93.                         //到达最后一页,显示“[首页] [上一页] [末页]” 
  94.                         str.append("<a href='"); 
  95.                         str.append(url); 
  96.                         str.append("?cpage=1&total="+total+"&url="+url); 
  97.                         str.append("'>[首页]</a> <a href='"); 
  98.                         str.append(url); 
  99.                         str.append("?cpage=" + (cpageInt - 1) + "&total=" + total+"&url="+url); 
 100.                         str.append("'>[上一页]</a> <a href='"); 
 101.                         str.append(url); 
 102.                         str.append("?cpage=" + total + "&total=" + total+"&url="+url); 
 103.                         str.append("'>[末页]</a>"); 
 104.                     } 
 105.                 } else { 
 106.                     //当前页与总页数不相同 
 107.                     if ("1".equals(cpage)) { 
 108.                         //第一页,显示“[首页] [下一页] [末页]” 
 109.                         str.append("<a href='"); 
 110.                         str.append(url); 
 111.                         str.append("?cpage=1&total="+total+"&url="+url); 
 112.                         str.append("'>[首页]</a> <a href='"); 
 113.                         str.append(url); 
 114.                         str.append("?cpage=" + (cpageInt + 1) + "&total=" + total+"&url="+url); 
 115.                         str.append("'>[下一页]</a> <a href='"); 
 116.                         str.append(url); 
 117.                         str.append("?cpage=" + total + "&total=" + total+"&url="+url); 
 118.                         str.append("'>[末页]</a>"); 
 119.                     } else { 
 120.                         //不是第一页,显示“[首页] [上一页] [下一页] [末页]” 
 121.                         str.append("<a href='"); 
 122.                         str.append(url); 
 123.                         str.append("?cpage=1&total="+total+"&url="+url); 
 124.                         str.append("'>[首页]</a> <a href='"); 
 125.                         str.append(url); 
 126.                         str.append("?cpage=" + (cpageInt - 1) + "&total=" + total+"&url="+url); 
 127.                         str.append("'>[上一页]</a> <a href='"); 
 128.                         str.append(url); 
 129.                         str.append("?cpage=" + (cpageInt + 1) + "&total=" + total+"&url="+url); 
 130.                         str.append("'>[下一页]</a> <a href='"); 
 131.                         str.append(url); 
 132.                         str.append("?cpage=" + total + "&total=" + total+"&url="+url); 
 133.                         str.append("'>[末页]</a>"); 
 134.                     } 
 135.                 } 
 136.             } 
 137.             
 138.             writer.write(str.toString()); 
 139.              
 140.         } catch (IOException ex) { 
 141.             Logger.getLogger(Pages.class.getName()).log(Level.SEVERE, null, ex); 
 142.         } 
 143.         return result; 
 144.     } 
 145. } 

package com.tangs.tag;

import com.opensymphony.xwork2.util.ValueStack;
import java.io.IOException;
import java.io.Writer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.struts2.components.Component;

/**
 * 分页逻辑Bean
 * @author tangs
 */
public class Pages extends Component {
    private String cpage;
    private String total;
    private String url;

    public String getCpage() {
        return cpage;
    }

    public void setCpage(String cpage) {
        this.cpage = cpage;
    }

    public String getTotal() {
        return total;
    }

    public void setTotal(String total) {
        this.total = total;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
   
   
    public Pages(ValueStack arg0) {
        super(arg0);
    }

    @Override
    public boolean start(Writer writer) {
        boolean result = super.start(writer);
        try {
            StringBuilder str = new StringBuilder();
            boolean isValid = true;
           
            //从ValueStack中取出数值
            if (isValid) {
                if (total.startsWith("%{") && total.endsWith("}")) {
                    total = total.substring(2, total.length() -1);
                    total = (String)this.getStack().findValue(total);
                    isValid = total == null ? false : true;
                } else {
                    isValid = false;
                }
            }
            if (isValid) {
                if (cpage.startsWith("%{") && cpage.endsWith("}")) {
                    cpage = cpage.substring(2, cpage.length() - 1);
                    cpage = (String)this.getStack().findValue(cpage);
                    isValid = cpage == null ? false : true;
                } else {
                    isValid = false;
                }
            }
            if (isValid) {
                if (url.startsWith("%{") && url.endsWith("}")) {
                    url = url.substring(2, url.length() - 1);
                    url = (String)this.getStack().findValue(url);
                    isValid = url == null ? false : true;
                } else {
                    isValid = false;
                }
            }

            if (isValid) {
                Integer cpageInt = Integer.valueOf(cpage);
                //当前页与总页数相等
                if (cpage.equals(total)) {
                    //如果total = 1,则无需分页,显示“[第1页] [共1页]”
                    if ("1".equals(total)) {
                        str.append("[第 " + cpage + " 页]");
                        str.append(" [共 " + total + " 页]");
                    } else {
                        //到达最后一页,显示“[首页] [上一页] [末页]”
                        str.append("<a href='");
                        str.append(url);
                        str.append("?cpage=1&total="+total+"&url="+url);
                        str.append("'>[首页]</a> <a href='");
                        str.append(url);
                        str.append("?cpage=" + (cpageInt - 1) + "&total=" + total+"&url="+url);
                        str.append("'>[上一页]</a> <a href='");
                        str.append(url);
                        str.append("?cpage=" + total + "&total=" + total+"&url="+url);
                        str.append("'>[末页]</a>");
                    }
                } else {
                    //当前页与总页数不相同
                    if ("1".equals(cpage)) {
                        //第一页,显示“[首页] [下一页] [末页]”
                        str.append("<a href='");
                        str.append(url);
                        str.append("?cpage=1&total="+total+"&url="+url);
                        str.append("'>[首页]</a> <a href='");
                        str.append(url);
                        str.append("?cpage=" + (cpageInt + 1) + "&total=" + total+"&url="+url);
                        str.append("'>[下一页]</a> <a href='");
                        str.append(url);
                        str.append("?cpage=" + total + "&total=" + total+"&url="+url);
                        str.append("'>[末页]</a>");
                    } else {
                        //不是第一页,显示“[首页] [上一页] [下一页] [末页]”
                        str.append("<a href='");
                        str.append(url);
                        str.append("?cpage=1&total="+total+"&url="+url);
                        str.append("'>[首页]</a> <a href='");
                        str.append(url);
                        str.append("?cpage=" + (cpageInt - 1) + "&total=" + total+"&url="+url);
                        str.append("'>[上一页]</a> <a href='");
                        str.append(url);
                        str.append("?cpage=" + (cpageInt + 1) + "&total=" + total+"&url="+url);
                        str.append("'>[下一页]</a> <a href='");
                        str.append(url);
                        str.append("?cpage=" + total + "&total=" + total+"&url="+url);
                        str.append("'>[末页]</a>");
                    }
                }
            }
          
            writer.write(str.toString());
           
        } catch (IOException ex) {
            Logger.getLogger(Pages.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
}

3.服务端

服务端主要是获得请求然后转向显示的页面

DisplayAction.java
Java代码

   1. /*
   2.  * To change this template, choose Tools | Templates
   3.  * and open the template in the editor.
   4.  */ 
   5.  
   6. package com.tangs.action; 
   7.  
   8. import com.opensymphony.xwork2.ActionSupport; 
   9.  
  10. /**
  11.  *
  12.  * @author tangs
  13.  */ 
  14. public class DisplayAction extends ActionSupport { 
  15.     private String cpage; 
  16.     private String total; 
  17.     private String url; 
  18.  
  19.     public String list() { 
  20.          
  21.         //Get data from server 
  22.         //... 
  23.         //这里没有做任何逻辑,直接跳转到了页面 
  24.         return SUCCESS; 
  25.     } 
  26.     public String getCpage() { 
  27.         return cpage; 
  28.     } 
  29.  
  30.     public void setCpage(String cpage) { 
  31.         this.cpage = cpage; 
  32.     } 
  33.  
  34.     public String getTotal() { 
  35.         return total; 
  36.     } 
  37.  
  38.     public void setTotal(String total) { 
  39.         this.total = total; 
  40.     } 
  41.  
  42.     public String getUrl() { 
  43.         return url; 
  44.     } 
  45.  
  46.     public void setUrl(String url) { 
  47.         this.url = url; 
  48.     } 
  49.      
  50.      
  51. } 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.tangs.action;

import com.opensymphony.xwork2.ActionSupport;

/**
 *
 * @author tangs
 */
public class DisplayAction extends ActionSupport {
    private String cpage;
    private String total;
    private String url;

    public String list() {
       
        //Get data from server
        //...
        //这里没有做任何逻辑,直接跳转到了页面
        return SUCCESS;
    }
    public String getCpage() {
        return cpage;
    }

    public void setCpage(String cpage) {
        this.cpage = cpage;
    }

    public String getTotal() {
        return total;
    }

    public void setTotal(String total) {
        this.total = total;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
   
   
}

  struts.xml
Xml代码

   1. <?xml version="1.0" encoding="UTF-8"?> 
   2. <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd" > 
   3. <struts> 
   4.     <package name="tagTest" extends="struts-default"> 
   5.                 <action name="list" class="com.tangs.action.DisplayAction"> 
   6.                     <result name="success">/list.jsp</result> 
   7.                 </action> 
   8.     </package> 
   9. </struts> 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd" >
<struts>
    <package name="tagTest" extends="struts-default">
                <action name="list" class="com.tangs.action.DisplayAction">
                    <result name="success">/list.jsp</result>
                </action>
    </package>
</struts>

 

4.在页面中使用标签

list.jsp
Html代码

   1. <%@page contentType="text/html" pageEncoding="UTF-8"%> 
   2. <%@ taglib prefix="tangs" uri="/WEB-INF/tangs.tld"%> 
   3. <%@ taglib prefix="s" uri="/WEB-INF/struts-tags.tld"%> 
   4.  
   5. <html> 
   6.     <head> 
   7.         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
   8.         <title>List</title> 
   9.     </head> 
  10.     <body> 
  11.         共 <s:property value="total"/> 页 第 <s:property value="cpage"/> 页<br> 
  12.         <tangs:pages cpage="%{cpage}" total="%{total}" url="%{url}"/> 
  13.     </body> 
  14. </html> 

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="tangs" uri="/WEB-INF/tangs.tld"%>
<%@ taglib prefix="s" uri="/WEB-INF/struts-tags.tld"%>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>List</title>
    </head>
    <body>
        共 <s:property value="total"/> 页 第 <s:property value="cpage"/> 页<br>
        <tangs:pages cpage="%{cpage}" total="%{total}" url="%{url}"/>
    </body>
</html>

 

好了,启动服务器,从浏览器中输入http://localhost:7001/TagTest/list.page?cpage=1& total=5&url=list.page

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值