JSP自定义标签(2)


四、编写有标签体的标签


需要返回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;
		}
	}
}


xiazdong.tld

    <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>






作者:xiazdong
出处:http://blog.xiazdong.info
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
原文地址:https://www.cnblogs.com/xiazdong/p/3058120.html