Java ---自定义标签(二)

     上篇文章的最后,我们自定义了一个带属性的标签,并使用它完成了一个简单的案例。其实到这我们已经可以看出来,前端jsp页面只需要写一个类似html语法的标签,就可以完成将集合中的数据取出来并展示这么相对复杂的操作。这就是我们使用标签的意义。接着上篇文章,我们看看怎么自定义一个带有标签体的标签。

一、开发带标签体的标签
     我们可以利用标签体来简化我们上一个案例中的标签处理类。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="mytid" prefix="mytag"%>
<html>
  <head>
    <title></title>
  </head>
  <body>
  <%
    HashMap<String,Integer> maps = new HashMap<String, Integer>();
    maps.put("李四",53);
    maps.put("张三",23);
    maps.put("walker",22);
    pageContext.setAttribute("map",maps);
  %>
      <table>
        <mytag:hello map="map">
            <tr>
              <td>${name}</td>
              <td>${age}</td>
            </tr>
        </mytag:hello>
      </table>
  </body>
</html>
<tag>
        <description>Outputs a colored tile</description>
        <name>hello</name>
        <tag-class>Test.MyTag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <name>map</name>
            <required>false</required>
            <fragment>true</fragment>
        </attribute>
    </tag>
public void doTag() throws JspException, IOException {
        HashMap<String,Integer> maps = (HashMap<String,Integer>)(getJspContext().getAttribute(map));
        for (String str : maps.keySet()){
            getJspContext().setAttribute("name",str);
            getJspContext().setAttribute("age",maps.get(str));
            getJspBody().invoke(null);

        }
    }
这里写图片描述

有些并没有改动的代码没有列出,只展示了关键的代码块。首先看jsp页面,有标签体的标签使用的时候是需要有开始标签和结束标签的,这一点是和html很像的。至于td元素中的内容,这是一个EL表达式,不知道的朋友可以快速百度下,这里的意思就是在当前页面寻找共享数据名为name和age的数据,找到就获取其值,否则为“”,非null。tld文件中的改动不多,就是将body-content的值改动成scriptless,这表示标签体可以是静态的html,但是不能是jsp脚本。而我们之前一直是empty,它指定该标签是没有标签体的。
     接下来看看我们标签处理类的改动,原先冗长的输出代码,被替换成以下三条语句:

getJspContext().setAttribute("name",str);
getJspContext().setAttribute("age",maps.get(str));
getJspBody().invoke(null);

前面两条语句很简单,在jsp页面设置page范围内的共享数据,主要是提供我们的标签中EL表达式使用。getJspBody()表示获取整个标签体的所有内容,返回的是一个fragment对象,这个对象的一个方法invoke就是用于输出整个内容到jsp页面,如果参数为null表示直接输出,还可以使用Writer作为参数传入,意思是将标签体的内容全部输入到这个字符流中,然后你可以通过一些操作,再次使用write方法输出到jsp页面。也就是说,如果对于标签体中的数据内容需要做一些判断操作的话,可以传递一个writer流,处理完成之后可以再次输出到页面上。

二、开发以页面片段为属性的标签
     我们的attribute可以上八种数据类型,因为jsp引擎是可以为我们自动转换并自动赋值到我们标签处理类的私有属性中,但是对于之外的类型都是不可以直接操作的,我们首先看如何以页面片段作为属性,传递。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="mytid" prefix="mytag"%>
<html>
  <head>
    <title></title>
  </head>
  <body>
      <mytag:hello>
          <jsp:attribute name="map">
              <h1>hello</h1>
          </jsp:attribute>
      </mytag:hello>
  </body>
</html>

我们使用jsp:attribute这个动作指令来完成给属性赋值上页面片段,name的值对应于tld中的属性name值。

<tag>
        <description>Outputs a colored tile</description>
        <name>hello</name>
        <tag-class>Test.MyTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>map</name>
            <required>false</required>
            <fragment>true</fragment>
        </attribute>
    </tag>

对于jsp页面以页面片段作为属性传入的参数,我们在标签处理类中是需要定义私有属性来接受的,在jsp中将页面片段定义为jspfregment类型,于是我们定义私有属性。

public class MyTag extends SimpleTagSupport {

    private JspFragment map;
    public JspFragment getMap(){
        return this.map;
    }
    public void setMap(JspFragment map){
        this.map = map;
    }
    @Override
    public void doTag() throws JspException, IOException {
        map.invoke(null);
    }
}

调用JspFragment 的invoke方法可以直接输出其中的内容。结果如下:


这里写图片描述

     稍微小结一下,之前我们传递属性值的时候是在标签名的后面添加属性名和属性值,但那时的属性值只限于字符串,你不能传递别的类型的内容。此处我们为了能够传递页面片段,通过jsp:attribute动作指令来给我们的属性赋值,而这个值的内容就是一个页面片段。上文中我们在介绍自定义标签体的时候,我们说可以使用getJspBody可以获得标签体的内容,其实这个方法返回的也是一个fregment,所以我们可以调用invoke方法输出标签体内容。

三、开发动态属性标签
     在我们之前介绍的内容中,传递的属性个数都是固定的,但是在实际开发中往往又会遇到有些参数必须传入有些选择性的传入,这样每个人传递的属性的个数都是不一样的,服务器端该如何处理呢?我们可以使用动态属性标签,使用此标签之前,我们的标签处理类就必须要继承接口DynamicAttributes,这个接口中就只有一个方法,setDynamicAttribute这个方法就是来完成动态的给我们传递的属性赋值。这是第一点,第二点就是需要在tld文件中配置一条语句,表名这个tag是支持动态属性的。下面是demo:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="mytid" prefix="mytag"%>
<html>
  <head>
    <title></title>
  </head>
  <body>
      <mytag:hello name="张三" age="23"/><hr/>
      <mytag:hello name="张三" age="23" student="ok"/><hr/>
      <mytag:hello name="张三" age="23" walker="yam"/>
  </body>
</html>
<tag>
        <description>Outputs a colored tile</description>
        <name>hello</name>
        <tag-class>Test.MyTag</tag-class>
        <body-content>scriptless</body-content>
        <dynamic-attributes>true</dynamic-attributes>
    </tag>
public class MyTag extends SimpleTagSupport implements DynamicAttributes{
    private ArrayList<String> keys = new ArrayList<String>();
    private ArrayList<Object> values = new ArrayList<Object>();

    @Override
    public void doTag() throws JspException, IOException {
        for(int i=0;i<keys.size();i++){
            getJspContext().getOut().write(""+keys.get(i)+values.get(i));
        }
    }
    @Override
    public void setDynamicAttribute(String var1, String var2, Object var3) throws JspException{
            keys.add(var2);
            values.add(var3);
    }
}
这里写图片描述

做一点解释,setDynamicAttribute这个方法中有三个参数,我们通常只使用后面两个参数,一个代表属性名,一个代表属性值。那么第一个参数表示什么意思呢?官方解释是:

uri - -the namespace of the attribute, or null if in the default namespace.

这是该属性的命名空间,如果没有显式指定就是null。我们暂时可以不用关心。

     最后还是要强调一点,属性的的只能使基本的数据类型,对于一些复杂的类型 ,例如Date,等,建议将该对象置于本页共享范围,然后标签处理类可以直接获取并做相应的处理。

     自定义标签介绍完了,如有错误,望指出!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 一、 自定义标签简介 自定义标签主要用于移除jsp页面中的java代码。工程(tag) 使用自定义标签移除jsp页...
    yjaal阅读 775评论 1 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,494评论 18 139
  • 本篇文章介绍自定义标签,可能在工作中很少涉及到自己来定义一个标签库,因为我们基本上都是使用的大神写的标签库,基本上...
    Single_YAM阅读 955评论 0 3
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,493评论 18 399
  • 一、JSP基础 1.1什么是JSP JSP(Java ServerPage)是Java服务器端动态页面技术。是su...
    晨星资源阅读 1,135评论 0 6