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();//Webページへの出力フローの取得
(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の使用


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