四、编写有标签体的标签
需要返回TagSupport.EVAL_BODY_INCLUDE,则可以进入标签体;
AttributeTag.java
package org.tagext; import javax.servlet.jsp.tagext.*; import javax.servlet.jsp.*; public class AttributeTag extends TagSupport{ private String name; public String getName(){ return name; } public void setName(String name){ this.name = name; } public int doStartTag()throws JspException{ Object value = null; value = super.pageContext.getAttribute(name,PageContext.PAGE_SCOPE); if(value==null){ return TagSupport.SKIP_BODY; } else{ return TagSupport.EVAL_BODY_INCLUDE; } } }
<tag> <name>attribute</name> <tag-class>org.tagext.AttributeTag</tag-class> <body-content>JSP</body-content> <attribute> <name>name</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag>
AttributeTag.jsp
<%@ page contentType="text/html" pageEncoding="GBK"%> <%@ taglib prefix="xiazdong" uri="xiazdong"%> <html> <head> <title></title> </head> <body> <% pageContext.setAttribute("xiazdong","12345"); %> <h1> <xiazdong:attribute name="xiazdong"> <h3>${pageScope.xiazdong}</h3> </xiazdong:attribute> </h1> </body> </html>
五、迭代标签
迭代标签的定义就是重复执行标签体,经常用在输出集合;在MVC中经常使用;
代码实例:
一些变化不大的文件我就不写了;
IterateTag.java
package org.tagext; import javax.servlet.jsp.tagext.*; import javax.servlet.jsp.*; import java.util.*; public class IterateTag extends TagSupport{ private String name; private String id; private Iterator<String> iter; public String getName(){ return name; } public void setName(String name){ this.name = name; } public String getId(){ return id; } public void setId(String id){ this.id = id; } public int doStartTag()throws JspException{ Object value = null; value = super.pageContext.getAttribute(name,PageContext.PAGE_SCOPE); if(value==null||!(value instanceof List<?>)){ return TagSupport.SKIP_BODY; } else{ iter = ((List<String>)value).iterator(); if(iter.hasNext()){ super.pageContext.setAttribute(id,iter.next()); return TagSupport.EVAL_BODY_INCLUDE; } else{ return TagSupport.SKIP_BODY; } } } public int doAfterBody()throws JspException{ if(iter.hasNext()){ super.pageContext.setAttribute(id,iter.next()); return TagSupport.EVAL_BODY_AGAIN; } else{ return TagSupport.SKIP_BODY; } } }
IterateTag.jsp
<%@ page contentType="text/html" pageEncoding="GBK" import="java.util.*"%> <%@ taglib prefix="xiazdong" uri="xiazdong"%> <html> <head> <title></title> </head> <body> <% List<String> list = new ArrayList<String>(); list.add("A"); list.add("B"); list.add("C"); pageContext.setAttribute("xiazdong",list); %> <h1> <xiazdong:iterate name="xiazdong" id="iter"> <h3>${iter}</h3> </xiazdong:iterate> </h1> </body> </html>
六、BodyTagSupport类
BodyTagSupport的特点就是可以将输出内容存在BodyContent中, 一次全部输出;
根据上面的迭代输出的代码,稍微变化即可,主要变化是在IterateTag.java中,需要extends BodyTagSupport;
BodyTagSupport的常用方法:
(1)BodyTagSupport.EVAL_BODY_BUFFERED;
(2)getPreviousOut(); //获得输出到网页的输出流
(3)bodyContent对象存储数据;
package org.tagext; import javax.servlet.jsp.tagext.*; import javax.servlet.jsp.*; import java.util.*; public class IterateTag extends BodyTagSupport{ private String name; private String id; private Iterator<String> iter; public String getName(){ return name; } public void setName(String name){ this.name = name; } public String getId(){ return id; } public void setId(String id){ this.id = id; } public int doStartTag()throws JspException{ Object value = null; value = super.pageContext.getAttribute(name,PageContext.PAGE_SCOPE); if(value==null||!(value instanceof List<?>)){ return TagSupport.SKIP_BODY; } else{ iter = ((List<String>)value).iterator(); if(iter.hasNext()){ super.pageContext.setAttribute(id,iter.next()); return TagSupport.EVAL_BODY_BUFFERED; //存在BodyContent中 } else{ return TagSupport.SKIP_BODY; } } } public int doAfterBody()throws JspException{ if(iter.hasNext()){ super.pageContext.setAttribute(id,iter.next()); return TagSupport.EVAL_BODY_AGAIN; } else{ return TagSupport.SKIP_BODY; } } public int doEndTag()throws JspException{ if(super.bodyContent!=null){ try{ super.bodyContent.writeOut(super.getPreviousOut()); //输出到页面 } catch(Exception e){} } return BodyTagSupport.EVAL_PAGE; } }
七、TagExtraInfo和VariableInfo的使用
在<jsp:useBean id = "">中的id属性表示对象名称,并且可以通过这个名称调用方法;而如果要实现这种效果,必须继承TagExtraInfo类;
我们需要另外创建一个文件,用以表明属性的对象能够在脚本中使用;
MyExtraInfo.java
package org.tag; import javax.servlet.jsp.tagext.*; public class MyTagExtraInfo extends TagExtraInfo{ public VariableInfo[] getVariableInfo(TagData data){ return new VariableInfo[]{new VariableInfo(data.getId(),"java.lang.String",true,VariableInfo.NESTED)}; } }
写完后在xiazdong.tld中添加:
<tei-class> //注意 org.tag.MyTagExtraInfo </tei-class>最后xiazdong.tld中以:
<tag>
<name>iterate</name>
<tag-class>org.tagext.IterateTag</tag-class>
<body-content>JSP</body-content>
<tei-class> //注意
org.tag.MyTagExtraInfo
</tei-class>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>id</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
这样在JSP中就能够在Scriptlet中使用;
<%@ page contentType="text/html" pageEncoding="GBK" import="java.util.*"%> <%@ taglib prefix="xiazdong" uri="xiazdong"%> <html> <head> <title></title> </head> <body> <% List<String> list = new ArrayList<String>(); list.add("A"); list.add("B"); list.add("C"); pageContext.setAttribute("xiazdong",list); %> <h1> <xiazdong:iterate name="xiazdong" id="iter"> <h3><%=iter%></h3> //注意,原本是${iter}输出; </xiazdong:iterate> </h1> </body> </html>