上篇文章的最后,我们自定义了一个带属性的标签,并使用它完成了一个简单的案例。其实到这我们已经可以看出来,前端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,等,建议将该对象置于本页共享范围,然后标签处理类可以直接获取并做相应的处理。

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

Java ---自定义标签(二)的更多相关文章

  1. Java ---自定义标签

         本篇文章介绍自定义标签,可能在工作中很少涉及到自己来定义一个标签库,因为我们基本上都是使用的大神写的标签库,基本上直接使用即可,但是从自身的发展来看,通往高级程序员的道路上,开发框架就需要大 ...

  2. java自定义标签 权限

    <?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="http://java ...

  3. java 自定义标签 传值

    <?xml version="1.0" encoding="UTF-8" ?>   <taglib xmlns="http://ja ...

  4. [转][Java]自定义标签简介

    作用:自定义标签主要用于移除 jsp 页面中的 java 代码. 实现:需要完成以下两个步骤: 编写一个实现 Tag 接口的 Java 类,把页面 java 代码移到这个 java 类中.(标签处理类 ...

  5. JSP2 自定义标签

    实现步骤 实现自定义标签的处理类继承javax.servlet.jsp.tagext.SimpleTagSupport,并重写doTag方法 建立标签库配置文件 在jsp中使用自定义标签 一个简单的标 ...

  6. javaweb学习总结(二十三)——jsp自定义标签开发入门

    一.自定义标签的作用 自定义标签主要用于移除Jsp页面中的java代码. 二.自定义标签开发和使用 2.1.自定义标签开发步骤 1.编写一个实现Tag接口的Java类(标签处理器类) 1 packag ...

  7. Java Spring Boot VS .NetCore (十一)自定义标签 Java Tag Freemarker VS .NetCore Tag TagHelper

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  8. java:tag 自定义标签应用

    一,tag类 1.1 TagMy标签类,格式化当前日期并输出 package com.dkt.tag; import java.io.IOException; import java.text.Sim ...

  9. javaweb(二十三)——jsp自定义标签开发入门

    一.自定义标签的作用 自定义标签主要用于移除Jsp页面中的java代码. 二.自定义标签开发和使用 2.1.自定义标签开发步骤 1.编写一个实现Tag接口的Java类(标签处理器类) 1 packag ...

随机推荐

  1. iOS开发tips-UIScrollView的Autlayout布局

    UIScrollViewj尽管继承于UIView,但它是一个相对比较特殊的视图,特别是当它遇到了AutoLayout之后.在UIScrollView中使用AutoLayout的目的除了使用相对约束确定 ...

  2. 【Zookeeper】源码分析之请求处理链(四)

    一.前言 前面分析了SyncReqeustProcessor,接着分析请求处理链中最后的一个处理器FinalRequestProcessor. 二.FinalRequestProcessor源码分析 ...

  3. web及H5 的链接测试

    1:先下载一个Xenu工具 2:安装完成之后,进入页面(将弹出框关闭) 3:进行设置(一般不用修改设置) 4:修改完成之后点击工具栏中的file按钮,并输入想要测试的URL地址 5:点击OK测试完成之 ...

  4. 每天一个linux命令(37)--iostat命令

    Linux 系统中的iostat是I/O statistics (输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视.它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况. ...

  5. java标签(label)求16进制字符串的整数和 把一个整数转为4个16进制字符表示

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #4f76cb } p.p2 { margin: 0.0px 0. ...

  6. for循环与foreach的区别

    for循环与foreach的区别 foreach 依赖 IEnumerable. 第一次 var a in GetList() 时 调用 GetEnumerator 返回第一个对象 并 赋给a, 以后 ...

  7. mfc---单文档工程添加消息响应

    写消息映射:.h中些函数头文件afx_mag … .cpp中写函数体 .cpp中写消息映射 给toolbar添加消息: .h中添加头文件afx_msg …. .cpp中添加函数体,消息映射ON_COM ...

  8. 11g R2 RAC启动关闭步骤

    1.关闭监听 /u01/app/11.2.0/grid/bin/srvctl stop listener -n redhat-rac01 /u01/app/11.2.0/grid/bin/srvctl ...

  9. 1708: [Usaco2007 Oct]Money奶牛的硬币

    1708: [Usaco2007 Oct]Money奶牛的硬币 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 544  Solved: 352[Submi ...

  10. C++primer拾遗(第二章:变量和基本类型)

    这是我对c++primer第二章的一个整理总结,算是比较适用于我自己吧,一小部分感觉不用提及的就省略了,只提了一下平时不注意,或者不好记住的内容. 排版太费劲了,直接放了图片格式.从自己的oneNot ...