评:



(1)



其实,开发自定义标签并不需要Struts2的支持,一般情况下,只需要继承



javax.servlet.jsp.tagext.BodyTagSupport类,重写doStartTag,doEndTag等方法即可。



 



在struts2.x中实现自定义标签时,继承的2个类分别是org.apache.struts2.views.jsp.ComponentTagSupport   和



org.apache.struts2.components.Component.



 



ComponentTagSupport:



实际上是对BodyTagSupport的一次封装,继承ComponentTagSupport类是为了获得JSP页面中用户自定义的标签中设置的属性值,并包装成Component对象。



Component:
继承Component类是为了从Struts2中的ValueStack中获得相对应的值。



 



(2)分析:



tag类里面,
须声明的属性:
需要定义你JSP页面传来的标签设置的属性。如maxlength,并相应的set get。



须的两个方法是:
1.
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res);
此 方法就是获得一个基本类的对象。在基本类里面需要有传入ValueStack的构造函数,如果基本类逻辑里面需要request或者response,那 么需要有传入ValueStack stack, HttpServletRequest req, HttpServletResponse res的构造函数;
2.
protected void populateParams()此方法是用来将JSP页面传来的属性值赋给基本类。这里是继承来的,所以首先调用super的相应方法。我理解上面第一 个方法返回的对象就是全局的一个Component对象,也就是第二个方法里面使用的对象。



 



(3)
实现过程分两步:
第一步,生成基本类,且将ValueStack值,还有其它可选值赋给它。
第二步,JSP页面传来的属性值,通过ComponentTagSupport,利用其getter,setter来获取.将JSP页面传来的属性值,赋给基本类实例。




实例:
(1)
页面:

<%@ taglib prefix="jason" uri="/WEB-INF/tlds/time.tld" %> 
   
<jason:jtime who="hwj" message="你好"/>



(2)
JtimeTag要定义tld文件中定义的各对应属性.


public class JtimeTag extends ComponentTagSupport { 
   
 private String message; 
   
 private String who; 
   
  

     public String getMessage() { 
   
  return message; 
   
 } 
   
  

     public void setMessage(String message) { 
   
  this.message = message; 
   
 } 
   
  

     public String getWho() { 
   
  return who; 
   
 } 
   
  

     public void setWho(String who) { 
   
  this.who = who; 
   
 } 
   
  
 
   
 public Component getBean(ValueStack arg0, HttpServletRequest arg1, 
   
   HttpServletResponse arg2) { 
   
  return new JtimeComponent(arg0); 
   
 } 
   
  

     protected void populateParams() { 
   
  super.populateParams(); 
   
  JtimeComponent jtime = (JtimeComponent) component; 
   
  jtime.setWho(who); 
   
  jtime.setMessage(message); 
   
 } 
   
}


(3)
JtimeTag要定义tld文件中定义的各对应属性.因为JtimeTag要赋值给它.:)

public class JtimeComponent extends Component { 
   
  
   
 private String message; 
   
  

     private String who; 
   
  
   
 private String a; 
   
  
   
  

     public String getMessage() { 
   
  return message; 
   
 } 
   
  

     public void setMessage(String message) { 
   
  this.message = message; 
   
 } 
   
  

     public String getWho() { 
   
  return who; 
   
 } 
   
  

     public void setWho(String who) { 
   
  this.who = who; 
   
 } 
   
  

     public JtimeComponent(ValueStack arg0) { 
   
  super(arg0); 
   
 } 
   
  
 
   //将自己需要输出的逻辑通过writer输出字符串就可以了。 
   
 public boolean start(Writer writer) { 
   
  boolean result = super.start(writer); 
   
  try { 
   
   a=this.getStack().findString("pageSize"); 
   
    writer.write(toHTML(who,message)); 
   
  } catch (IOException ex) { 
   
  } 
   
   
   
  return result; 
   
 } 
   
  
   
 protected String toHTML(String who,String message) { 
   
  Date date=new Date(); 
   
  return who+message+" 当前的时间是:"+date+"页面数:"+a; 
   
 } 
   
}



(4)

<taglib>    
   
    <tlib-version>2.2.3</tlib-version>    
   
    <jsp-version>1.2</jsp-version>    
   
    <short-name>my</short-name>    
   
    <uri>/jtime</uri>  -无起作用     
   
    <display-name>"jason time tab"</display-name>    
   
        <tag>    
   
            <name>jtime</name>    
   
            <tag-class>com.coship.dhm.dm.common.taglib.JtimeTag</tag-class>     
   
            <body-content>empty</body-content>        
   
            <attribute>    
   
                <name>message</name>    
   
                <required>false</required>    
   
                <rtexprvalue>true</rtexprvalue>    
   
            </attribute>  
   
            <attribute>    
   
                <name>who</name>    
   
                <required>true</required>    
   
                <rtexprvalue>true</rtexprvalue>    
   
            </attribute> 
   
        </tag>    
   
</taglib>


(5)
执行过程:
1
页面打开时,load入<%@ taglib prefix="jason" uri="/WEB-INF/tlds/time.tld" %>;
当程序读到"<jason"时,会根据上面的标签定义到time.tld-->JtimeTag.java;
2.
JtimeTag继承ComponentTagSupport,会将JSP页面标签属性进行获取,因为此类有定义各属性及其getter,setter -->



生成一个基本类实例,赋值-->将各属性值赋给基本类实例.
3.
基本类实例,执行start()方法-->执行super.start()-->获取action中的属性-->将自定义的信息用writer.write()输出.