`

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

阅读更多
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.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 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

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
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
/*
 * 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 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
<%@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>

分享到:
评论
1 楼 hilliate 2009-09-10  
第一步,把冰箱门打开
第二步,把大象装进去
第三步,把冰箱门关上

呵呵

相关推荐

    struts2自定义标签案例详解

    Struts2中实现自定义标签很简单,主要分为3步: 1.创建taglib文件(.tld),编写标签声明。 2.编写自定义标签类。 3.在页面中使用标签。 下面以一个自定义的分页标签为例,进行说明。 其实,开发自定义标签并不...

    struts2 学习例子

    Struts2标签库提供了主题、模板支持,极大地简化了视图页面的编写,而且,struts2的主题、模板都提供了很好的扩展性。实现了更好的代码复用。Struts2允许在页面中使用自定义组件,这完全能满足项目中页面显示复杂,...

    struts2 标签库 帮助文档

    struts2框架的标签库分为三类: 用户标签:生成HTML元素 非用户标签:数据访问、逻辑控制等。 AJAX标签:支持AJAX技术。 用户界面标签又分两类: 表单标签:生成HTML页面的from元素 非表单标签:生成页面上的...

    Struts2+API+标签全解+网页说明

    非界面标签又分为数据访问标签和流程控制标签。 控制标签: if/elseif/else标签:控制流程分支。 iteratot标签:对集合属性迭代(属性类型:List、Map、数组)。 append标签:将多个集合对象拼接在一起,组成...

    Struts网络编程例学与实践 源码

    第8-11章是Struts比较高级的内容,包括Struts自定义标签、Struts校验机制、Struts国际化方法和Struts的Tickes组件;第12章是一个完整实例,结合Eclipse、Ant等内容,搭建了一个真实的开发环境和实际的应用。 本书在...

    Java Web整合开发王者归来(JSP+Servlet+Struts+Hibernate+Spring)

    第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为Struts框架篇,内容不仅包括Struts 1.x的内容,也包括Struts 2.x中的内容;第5篇为Hibernate框架...

    java简历范文.zip

    优秀的java开发工程师、应届生、实习生、3-5年经验...页面采用Html ,CSS, JQuery等技术,后台使用Hibernate, Struts2 ,Spring3 的MVC架构,主要应用为hibernate的ORM,struts2 的OGNL, 标签库,拦截器,Spring的AOP等。

    -SMART系统-系统框架设计与开发.zipspringbootSMART系统是一个新型智能在线考试信息管理系统,该系统主要实现

    springbootSMART系统是一个新型智能在线考试信息管理系统,该系统主要实现了学生在线考试与评估以及教师对学生在线考试信息的管理和维护。本文按照SMART系统的非功能性需求,基于Struts、Spring、Hibernate三种开源...

    ## E鹰新闻发布系统 Java

    ## E鹰新闻发布系统 ###Description: 采用到的技术:JSP+... 前台制作采用标签制,分为系统标签和用户自义义标签两种,系统标签是自代的,用户不可以修改,而自定义标签则是用户根据相应的功能自己定制出来的,

    Java Web整合开发王者归来:Java Web.part2

    第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为Struts框架篇,内容不仅包括Struts 1.x的内容,也包括Struts 2.x中的内容;第5篇为Hibernate框架...

    E鹰新闻发布系统111

    采用到的技术:JSP+Struts+JSTL+EL,...前台制作采用标签制,分为系统标签和用户自义义标签两种,系统标签是自代的,用户不可以修改,而自定义标签则是用户根据相应的功能自己定制出来的,固此,可以自行删除或修改!

    Java.Web整合开发王者归来.part2

    第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等; 第4篇为Struts框架篇,内容不仅包括Struts 1.x的内容,也包括Struts 2.x中的内容; 第5篇为Hibernate...

    Java Web整合开发王者归来2/16

    第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、 资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为Struts框架篇,内容不仅包括Struts 1.x的内 容,也包括Struts 2.x中的内容;第5篇为Hibernate...

    Java Web整合开发王者归来(共4部分含源代码)part2

    第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为Struts框架篇,内容不仅包括Struts 1.x的内容,也包括Struts 2.x中的内容;第5篇为Hibernate框架...

    Java Web整合开发王者归来:Java Web.part3

    第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为Struts框架篇,内容不仅包括Struts 1.x的内容,也包括Struts 2.x中的内容;第5篇为Hibernate框架...

    Java.Web整合开发王者归来.part2.rar (共3部分)

    第3篇为高级篇,内容包括JSTL标签库的 使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等 ;第4篇为Struts框架篇,内容不仅包括Struts 1.x的内容,也包括Struts 2.x中的内容;第5篇为Hibernate...

    Java Web整合开发王者归来(共4部分含源代码)part3

    第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为Struts框架篇,内容不仅包括Struts 1.x的内容,也包括Struts 2.x中的内容;第5篇为Hibernate框架...

    Java.Web整合开发王者归来.part3

    第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等; 第4篇为Struts框架篇,内容不仅包括Struts 1.x的内容,也包括Struts 2.x中的内容; 第5篇为Hibernate...

    Java Web整合开发王者归来(共4部分含源代码)part1

    第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为Struts框架篇,内容不仅包括Struts 1.x的内容,也包括Struts 2.x中的内容;第5篇为Hibernate框架...

    Java Web整合开发王者归来3/16

    第3篇为高级篇,内容包括JSTL标签库的使用、如何自定义标签、 资源国际化、数据库概述、JDBC详解、XML概述等;第4篇为Struts框架篇,内容不仅包括Struts 1.x的内 容,也包括Struts 2.x中的内容;第5篇为Hibernate...

Global site tag (gtag.js) - Google Analytics