四、编写有标签体的标签
需要返回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>