1). 若一个自定义标签有标签体:
<nchu:hello> HelloWorld </nchu:hello>
在自定义标签的标签处理器中使用 JspFragment 对象封装标签体信息.
2). 若配置了标签含有标签体, 则 JSP 引擎会调用 setJspBody() 方法把 JspFragment 传递给标签处理器类
在 SimpleTagSupport 中还定义了一个 getJspBody() 方法, 用于返回 JspFragment 对象.
3). JspFragment 的 invoke(Writer) 方法: 把标签体内容从 Writer 中输出, 若为 null,
则等同于 invoke(getJspContext().getOut()), 即不对标签体内容处理,直接把标签体内容输出到页面上
有时, 可以 借助于 StringWriter, 可以在标签处理器类中先得到标签体的内容:
//利用 StringWriter 得到标签体的内容. StringWriter sw = new StringWriter(); bodyContent.invoke(sw);
4). 在 tld 文件中, 使用 body-content 节点来描述标签体的类型:
<body-content>: 指定标签体的类型, 大部分情况下, 取值为 scriptless。可能取值有 3 种:
- empty: 没有标签体
- scriptless: 标签体可以包含 el 表达式和 JSP 动作元素,但不能包含 JSP 的脚本元素
- tagdependent: 表示标签体交由标签本身去解析处理。若指定 tagdependent,在标签体中的所有代码都会原封不动的交给标签处理器,而不是将执行结果传递给标签处理器
<body-content>scriptless</body-content>
自定义forEach标签
1.标签处理器:
package yang.mybatis.tag; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; import java.io.IOException; import java.util.Collection; /** * Created by yangshijing on 2017/11/24 0024. */ public class ForEachTag extends SimpleTagSupport { private Collection<?> items; private String var; public void setItems(Collection<?> items) { this.items = items; } public void setVar(String var) { this.var = var; } @Override public void doTag() throws JspException, IOException { //遍历集合 if(items != null) { for (Object item : items) { //把遍历中的对象放入PageContext域中;键:var 值:正在遍历的对象 getJspContext().setAttribute(var, item); //不对标签体处理,直接输出到页面 getJspBody().invoke(null); } } } }
2.自定义.tld文件
<tag> <!--自定义遍历集合标签--> <name>forEach</name> <!--标签所在的全类名--> <tag-class>yang.mybatis.tag.ForEachTag</tag-class> <!--标签体的类型--> <body-content>scriptless</body-content> <!-- 描述当前标签的属性 --> <attribute> <!-- 属性名 --> <name>items</name> <!-- 该属性是否必须 --> <required>true</required> <!-- rtexprvalue: runtime expression value 当前属性是否可以接受运行时表达式的动态值 --> <!--例如El表达式--> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>var</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag>
Jsp页面
<%@ page import="yang.mybatis.domain.Customer" %> <%@ page import="java.util.List" %> <%@ page import="java.util.ArrayList" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%--导入标签库描述文件--%> <%@ taglib prefix="nchu" uri="http://mycompany.com" %> <html> <head> <title>Title</title> </head> <body> <% List<Customer> customers = new ArrayList<Customer>(); customers.add(new Customer(1, "Yang","13112233445","Shanghai")); customers.add(new Customer(2, "Zhang","13543214243","Beijiing")); customers.add(new Customer(3, "XIe","13343242342","HeNan")); customers.add(new Customer(4, "Liu","13334234334","ZhengZhou")); customers.add(new Customer(5, "Xiong","13342343243","ShanDong")); request.setAttribute("customers", customers); %> <nchu:forEach items="${customers}" var="customer"> 账号:${customer.id} <br> 姓名:${customer.name} <br> 电话:${customer.phone} <br> 地址:${customer.address} <br><br> </nchu:forEach> </body> </html>
总结:El表达式${}是从隐藏域中获取值,所以在将值放入PageContext域中即可在页面上使用EL表达式显示内容