JSP的自定义标签(二)

自定义标签的功能扩展

自定义标签的其中一个作用就是替换jsp中的scriptlet代码,提高该程序段的重用性。为此肯定需要更多样化的功能以满足不同需求。通常有三种方法来拓展自定义标签的功能:
    1.创建标签属性.
    2.建立代码段变量.
    3.使用标签额外信息类(TEI).


1.创建自定义标签的属性

功能需求

在上个显示当前时间的例子中格式是固定在处理类中的,可不可以在jsp中通过标签来设置呢,这里就需要一个该标签的属性用来设置时间格式。

实践

修改标签处理程序类,将原来的固定字符串改为变量,并为此变量设置set方法。这里的set方法类似于javaBean规范中的,方便与tld文件的属性关联。

    public class TagProcess extends TagSupport {
    private String timeFormat;
    @Override
    public int doEndTag() throws JspException {
        String time = new  SimpleDateFormat(timeFormat).format(new Date());
        try {
            pageContext.getOut().print(time);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return EVAL_PAGE;
    }
    public void setTimeFormat(String timeFormat) {
        this.timeFormat = timeFormat;
    }
}

修改TLD文件中的tag标签,加入属性:

<tag>
  <name>nowTime</name>
  <tag-class>javaBeansInJSP.TagProcess</tag-class>
  <body-content>empty</body-content>
  <attribute>
   <name>timeFormat</name>
   <rtexprvalue>false</rtexprvalue>
   <type>java.lang.String</type>
  </attribute>
 </tag>

去JSP页面中设置该属性值:

<body>
now let’s look at the time :<timem:nowTime timeFormat = "YY-MM-DD  hh:mm:ss"/>
</body>

显示如下:
这里写图片描述

原理

在tld文件的tag标签里面加入属性标签<attribute>标签,设置其名称,类型等等。并在标签处理类中设置该属性,属性名称和标签里的一样,添加set方法。在jsp文件里标签中为属性赋值就在标签处理程序中使用。
attribute标签的一些子属性设置,required设置为true的话意思是你必须要为该属性设置值,rtexprvalue设置为true意思是该属性值可以设置成scriptlet的计算结果也可以为该属性设置任何类型的对象。

2.建立代码段变量

需求

有时候我们需要标签内的属性或者说变量能够直接在jsp中使用,为了实现这种交互呢,有两种方式可以实现,一种是TLD文件中声明,另一种是使用TEI类。
可以看一个例子,我想在jsp页面中显示一个数组的所有元素,可以用如下方法。这个例子只做演示。
这是一个标签处理类(对应于ADC标签库里的createADC标签),在类里面有个数组,我直接写死,然后设置到pageContext里面如下:

    public class CreateADCs extends TagSupport{
    private List<String> adcs = Arrays.asList("麦林炮手","奥巴马","薇恩");
    @Override
    public int doEndTag(){
        pageContext.setAttribute("ADCS", adcs);
        return EVAL_BODY_INCLUDE;
    }
}

再在jsp页面中,创建标签执行添加操作之后,再用scriptlet代码从pageContext获取,之所以这么做是标签内的变量没法与jsp直接交互数据。

<body>
    <ADC:createADC/>
    <%
    List<String> ADCS=(List<String>)pageContext.getAttribute("ADCS");
    %>
    <br>
    <h1>There are the adcs</h1>
    <%
    for (String adc:ADCS) {
        out.print(adc+"   "); 
    }%>
</body>

显示结果如下:
这里写图片描述

在TLD文件中创建标签变量

为了解决以上的麻烦,我们使用标签变量。
标签处理类不变,仍旧往ADCS里面放数据,在TLD里面声明这么一个ADCS变量。它会自动得到pageContext的attribute为值为自己初始化。tld文件改变如下:

 <tag>
  <name>createADC</name>
  <tag-class>javaBeansInJSP.CreateADCs</tag-class>
  <body-content>empty</body-content>
  <variable>
   <name-given>ADCS</name-given>
   <variable-class>java.util.List&lt;String&gt;</variable-class>
   <declare>true</declare>
   <scope>AT_END</scope>
  </variable>
 </tag>

在jsp文件中直接访问这个变量ADCS即可:

    <body>
        <ADC:createADC/>
        <br>
        <h1>There are the adcs</h1>
        <%
        for (String adc:ADCS) {
            out.print(adc+"   "); 
        }
        %>
    </body>
细节
atrribute属性描述
description*该变量的相关信息
name-given / name-from-attribute变量名
variable-class?变量类型
declare?是否是新的变量。默认值为true,表示新建该变量
scope?该变量的生效范围。AT_BEGIN|NESTED|AT_END 分别表示在标签起始、只在标签内、标签结束 开始生效。
用TEI类来创建该变量

另外一种方式来创建该变量就是用tag标签里的tei类来实现。
首先建立一个这样的TEI类,继承variableInfo类,实现其方法:

public class CreateSkillTEI extends TagExtraInfo {
    @Override
    public VariableInfo[] getVariableInfo(TagData data) {
        // TODO Auto-generated method stub
        VariableInfo vi = new VariableInfo(data.getAttributeString("adcsName"),
            data.getAttributeString("adcsType"), true, VariableInfo.AT_END);
        VariableInfo[] tagVariables = new VariableInfo[1];
        tagVariables[0]=vi;
        return tagVariables;
    }
}

上边代码中,返回的是变量的数组,可以实现创建多个变量返回给jsp,传入值为该tei类所对属标签的对应标签类的数据,通过该tagdata可以获取标签类里面的属性,用来设置该变量。variableInfo的四个参数和tld创建标签变量时一样。我们获取了两个属性name和type,就需要在标签类里面设置:

public class CreateSkill    extends TagSupport {
    private List<String> skillList= Arrays.asList("圣枪洗礼","毁灭射击","终极时刻");
    private String adcsName="defaultName";
    private String adcsType="java.util.List<String>";
    @Override
    public int doStartTag() throws JspException {
        // TODO Auto-generated method stub
        pageContext.setAttribute(adcsName, skillList);
        return EVAL_BODY_INCLUDE;
    }
    public void setAdcsName(String adcsName) {
        this.adcsName = adcsName;
    }
    public void setAdcsType(String adcsType) {
        this.adcsType = adcsType;
    }
}

如上设置了两个属性,并且向JSP页面设置了变量值。只需要再在tld里面配置属性,配置tei-class就好了:

<tag>
  <name>createSkill</name>
  <tag-class>javaBeansInJSP.CreateSkill</tag-class>
  <tei-class>javaBeansInJSP.CreateSkillTEI</tei-class>
  <body-content>JSP</body-content>
  <attribute>
   <name>adcsName</name>
   <required>true</required>
   <rtexprvalue>true</rtexprvalue>
   <type>java.lang.String</type>
  </attribute>
  <attribute>
   <name>adcsType</name>
   <required>true</required>
   <rtexprvalue>true</rtexprvalue>
   <type>java.lang.String</type>
  </attribute>
 </tag>

在jsp中使用:

    <h1>There are the skills</h1>
    <ADC:createSkill adcsName ="someSkills" adcsType="java.util.List<String>" />
    <%
        out.print(someSkills); 
    %>

上边代码在eclipse里面报错,不认为someSkills是一个变量,事实上可以运行。而且可以在里面读到变量值:
这里写图片描述

总结:

自定义标签通过添加属性获得了更丰富的表达和灵活的处理,但是当与jsp页面交互的时候需要用pageContext来传递对象,同时jsp又是需要为jsp页面创建标签对象,这时候用tei为标签加入属性name,type,并作用到创建的标签对象上,就可以直接在自定义标签里面用该标签的属性来创建JSP里面直接用的变量了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值