我在做标签的时候发现有时候嵌套标签在jsp显示的时候非常重要. 特地拿来和大家一起分享.
我以开发一个 switch 标签为例.
1,首先要写三个标签类.
package com.cao.tag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
public class SwitchTag extends TagSupport {
private boolean subTagExecuted = false;
//这个方法由子标签对象处理器调用,用于判断是否可以执行自身的标签体.
public synchronized boolean getPerimission(){
return !this.subTagExecuted;
}
//如果一个子标签执行成功,则调用这个方法通知父标签. 这样其他子标签将忽略标签体从而实现Switch case 的功能.
public synchronized void subTagSuccessed(){
this.subTagExecuted = true;
}
@Override
public int doEndTag() throws JspException {
return super.doEndTag();
}
@Override
public int doStartTag() throws JspException {
this.subTagExecuted = false;
return this.EVAL_BODY_INCLUDE;
}
@Override
public void release() {
this.subTagExecuted = false;
}
}
-----------------------------------------------------------------------------------------------------
package com.cao.tag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.Tag;
public class CaseTag extends BodyTagSupport{
private boolean cond = false;
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
return super.doEndTag();
}
@Override
public int doStartTag() throws JspException {
Tag parent = this.getParent();
//完成父子标签之间的通信.
SwitchTag parentObj = (SwitchTag) parent;
//判断是否执行自身的标签体.
if(!parentObj.getPerimission()){
return this.SKIP_BODY;
}
//如果条件为true 则通知父标签 已经有一个满足条件的子标签了.
// 否则 忽略标签体
if(cond){
parentObj.subTagSuccessed();
return this.EVAL_BODY_INCLUDE;
}else{
return this.SKIP_BODY;
}
}
@Override
public void release() {
// TODO Auto-generated method stub
cond = false;
}
public void setCond(boolean cond) {
this.cond = cond;
}
}
--------------------------------------------------------------------------------
package com.cao.tag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.Tag;
public class DefaultTag extends BodyTagSupport {
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
return super.doEndTag();
}
@Override
public int doStartTag() throws JspException {
Tag parent = this.getParent();
//与父标签通信.
SwitchTag parentObj = (SwitchTag) parent;
if(!parentObj.getPerimission()){
return this.SKIP_BODY;
}
//通知父标签
parentObj.subTagSuccessed();
return this.EVAL_BODY_INCLUDE;
}
}
---------------------
2,配置 TLD 文件. <uri> 为 < uri > /myTag</uri>
<tag>
<name>switch</name>
<tag-class>com.cao.tag.SwitchTag</tag-class>
<body-content>JSP</body-content>
</tag>
<tag>
<name>case</name>
<tag-class>com.cao.tag.CaseTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>cond</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>default</name>
<tag-class>com.cao.tag.DefaultTag</tag-class>
<body-content>JSP</body-content>
</tag>
3 在 index.jsp 上访问
http://localhost:8080/tagPro/index.jsp?name=caoyinghui
<%
String name = request.getParameter("name");
%>
<body>
<my:switch>
<my:case cond="<%=name.equals("caoyinghui") %>">
<%out.println(name+" is my name!"); %>
</my:case>
<my:case cond="<%=name.equals("tulu") %>">
<%out.println(name +" is my girlfriend!"); %>
</my:case>
<my:default>
<%out.println("I don't know!"); %>
</my:default>
</my:switch>
</body>
输入不同的name 可以得到不同的结果