1. 标签语言特点
<开始标签 属性="属性值">标签体</结束标签>
空标签
<br/><hr/>
<开始标签></结束标签>
<开始标签/>
2. 自定义标签的开发及使用步骤
1. 创建一个标签助手类(继承BodyTagSupport)
标签属性必须与助手类的属性对应、且要提供对应get/set方法
rtexprvalue2. 创建标签库描述文件(tld),添加自定义标签的配置
注:tld文件必须保存到WEB-INF目录或其子目录
jstl标签库3. 在JSP通过taglib指令导入标签库,并通过指定后缀访问自定义标签
3. 标签生命周期
流程A:
SKIP_BODY
1. 实例化标签助手类->doStartTag()------------->doEndTag()
//主要用开发简单标签流程B:
EVAL_BODY_INCLUDE SKIP_BODY
2. 实例化标签助手类->doStartTag()------------->doAfterBody---------------->doEndTag()...
EVAL_BODY_AGAIN
3.
jrebal 热加载
SKIP_BODY:跳过主体
EVAL_BODY_INCLUDE:计算标签主体内容并[输出]
EVAL_PAGE:计算页面的后续部分
SKIP_PAGE:跳过页面的后续部分
EVAL_BODY_AGAIN:再计算主体一次
案例
if
package com.zking.zy; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; public class IfTag extends BodyTagSupport{ private Boolean test; public Boolean getTest() { return test; } public void setTest(Boolean test) { this.test = test; } //方法一 /*@Override public int doStartTag() throws JspException { return test?EVAL_BODY_INCLUDE:SKIP_BODY; }*/ //方法二 @Override public int doStartTag() throws JspException { if(test) { return EVAL_BODY_INCLUDE; } else { return SKIP_BODY; } } }
xml
<tag> <!-- 标签名 --> <name>if</name> <!-- 标签工具类 --> <tag-class>com.zking.zy.IfTag</tag-class> <!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 --> <body-content>jsp</body-content> <!-- 自定义标签的属性定义,请注意一定要在标签类中提供对应的get/set方法 --> <attribute> <!-- 自定义标签的属性名称 --> <name>test</name> <!-- true表示必填 --> <required>true</required> <!-- true支持动态值,可以向值里面填jsp表达式、EL表达式,false则不支持 --> <rtexprvalue>true</rtexprvalue> </attribute> </tag>
index.jsp
<body> <% String[] stu = {"aa","bb","cc"}; request.setAttribute("stu", stu); %> <z:if test="${not empty stu}"> wfefe </z:if> </body>
out
package com.zking.zy; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; public class OutTag extends BodyTagSupport{ @Override public int doEndTag() throws JspException { return EVAL_PAGE; } @Override public int doStartTag() throws JspException { return EVAL_BODY_INCLUDE; } }
wxl
<tag> <!-- 标签名 --> <name>out</name> <!-- 标签工具类 --> <tag-class>com.zking.zy.OutTag</tag-class> <!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 --> <body-content>jsp</body-content> <!-- 自定义标签的属性定义,请注意一定要在标签类中提供对应的get/set方法 --> <!-- <attribute> 自定义标签的属性名称 <name>test</name> true表示必填 <required>true</required> true支持动态值,可以向值里面填jsp表达式、EL表达式,false则不支持 <rtexprvalue>true</rtexprvalue> </attribute> --> </tag>
index.jsp
<z:out>sdwdwd</z:out>
forEach
package com.zking.zy; import java.util.Iterator; import java.util.List; import java.util.Objects; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; public class ForEachTag extends BodyTagSupport{ //循环数组 /*private String[] items; private String var; public String[] getItems() { return items; } public void setItems(String[] items) { this.items = items; } public String getVar() { return var; } public void setVar(String var) { this.var = var; } @Override public int doStartTag() throws JspException { String str = ""; for (String s : items) { str += s; } pageContext.setAttribute(var, str); return EVAL_BODY_INCLUDE; }*/ //循环集合 //存放数据源 private List<Object> items; //每次循环获取的对象放入pageContext中,并以var属性的值为key进行保存 //示例: 页面上标签var属性指定为item,则每次循环取出的对象(obj)将执行如下: //pageContext.setAttribute("item", obj); //页面中可以使用EL表达式取出对象中的属性, 如: ${item.name} private String var; public List<Object> getItems() { return items; } public void setItems(List<Object> items) { this.items = items; } public String getVar() { return var; } public void setVar(String var) { this.var = var; } @Override public int doStartTag() { if(Objects.isNull(this.items) || this.items.size() == 0) { return SKIP_BODY; } Iterator<Object> iterator = this.items.iterator(); Object obj = iterator.next(); this.pageContext.setAttribute(var, obj); this.pageContext.setAttribute("iterator", iterator); return EVAL_BODY_INCLUDE; } @Override public int doAfterBody() { Iterator<Object> it = (Iterator<Object>)this.pageContext.getAttribute("iterator"); if(it.hasNext()) { this.pageContext.setAttribute(var, it.next()); return EVAL_BODY_AGAIN; } return SKIP_BODY; } }
wxl
<tag> <!-- 标签名 --> <name>forEach</name> <!-- 标签工具类 --> <tag-class>com.zking.zy.ForEachTag</tag-class> <!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 --> <body-content>jsp</body-content> <!-- 自定义标签的属性定义,请注意一定要在标签类中提供对应的get/set方法 --> <attribute> <!-- 自定义标签的属性名称 --> <name>items</name> <!-- true表示必填 --> <required>true</required> <!-- true支持动态值,可以向值里面填jsp表达式、EL表达式,false则不支持 --> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <!-- 自定义标签的属性名称 --> <name>var</name> <!-- true表示必填 --> <required>true</required> <!-- true支持动态值,可以向值里面填jsp表达式、EL表达式,false则不支持 --> <rtexprvalue>false</rtexprvalue> </attribute> </tag>
index.jsp
<body> <% String[] stu = {"aa","bb","cc"}; request.setAttribute("stu", stu); List<Object> dd = new ArrayList<Object>(); dd.add("dwd"); dd.add("gdg"); dd.add("tyy"); request.setAttribute("ss", dd); %> <!-- 遍历集合 --> <z:forEach items="${dd}" var="s"> ${s} </z:forEach> <!-- 遍历数组 --> <%-- <z:forEach items="${stu}" var="s"> ${s} </z:forEach> --%> </body>