分类: Java
2008-12-15 11:34:57
(1)第一步:开发标签实现类。
helloTagHaveProp.java
package hello;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
public class helloTagHaveProp extends TagSupport {
private String fontSize="3";//字体大小,默认3号
private String fontColor="#000000";//字体颜色,默认黑色
//----标签开始时调用此方法-------
public int doStartTag(){
try{
JspWriter out=pageContext.getOut();
out.print("标签开始了。 "\" size=\""+fontSize+"\">hello!");
}catch(Exception e){
System.out.println(e);
}
return EVAL_BODY_INCLUDE;
}
//----标签结束时调用此方法-------
public int doEndTag(){
try{
JspWriter out=pageContext.getOut();
out.print("标签结束了。");
}catch(Exception e){
System.out.println(e);
}
return EVAL_PAGE;
}
public String getFontColor() {
return fontColor;
}
public void setFontColor(String fontColor) {
this.fontColor = fontColor;
}
public String getFontSize() {
return fontSize;
}
public void setFontSize(String fontSize) {
this.fontSize = fontSize;
}
}
(2)第二步:编写标签描述tld文件。这里在myTag.tld文件中增加内容,在
其中,name为属性的名称,required设置此属性是否必须设置,如果为true则在页面中使用此标签时,必须给标签的这个属性赋值。
(3)第三步:在应用的.xml文件中声明标签库引用。本例与实例108使用同一个tld文件,故不必再修改。
(4)第四步:在JSP页面中声明并调用标签。
useHelloTagHaveProp.jsp
<%@ taglib uri="/myTag" prefix="myTag" %>
<%@ page contentType="text/html;charset=GB2312" %>
编写标签对应的实现类时,需要重载BodyTagSupport类几个方法:doStartTag(), setBodyContent(), doInitBody(), doAfterBody(), doEndTag(),他们执行顺序如下:doStartTag()→doInitBody()→setBodyContent()→doAfterBody()→doEndTag()doStartTag()方法可返回EVAL_BODY_INCLUDE或SKIP_BODY,如果返回EVAL_BODY_ INCLUDE则继续执行;如果返回SKIP_BODY则接下来的doInitBody(),setBodyContent(), doAfterBody()三个方法不会被执行,而直接执行doEndTag()方法。
setBodyContent()方法用于设置标签体内容,如果在此之前要作一些初始化工作,则在doInitBody()方法中完成。标签体内容执行完后,会调用doAfterBody()方法,此方法可返回EVAL_BODY_TAG, SKIP_BODY,
EVAL_PAGE或SKIP_PAGE。如果返回EVAL_BODY_TAG则会再次设置标签体内容,直到返回SKIP_BODY;如果返回EVAL_PAGE则标签体执行完后会继续执行页面中接下来的部分;如果返回SKIP_PAGE,则JSP页面的后续内容将不再执行。
【实例110】 开发带标签体的标签:bodyTag1
本实例将要开发一个带标签体的标签bodyTag1,这个标签有一个属性countNum,用于设置输出标签体内容的次数,输出内容为当前的系统时间。
(1)第一步:开发标签实现类。
BodyTag1.java
package body;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class bodyTag1 extends BodyTagSupport{
private int currentNum=1;//当前执行次数
//----标签开始时调用此方法-------
public int doStartTag(){
try{
JspWriter out=pageContext.getOut();
out.print("标签开始了:
");
if(countNum>0)
return EVAL_BODY_TAG;
else
return SKIP_BODY;
}catch(Exception e){
System.out.println(e);
return SKIP_BODY;
}
}
//----标签体执行完后调用此方法----
public int doAfterBody(){
try{
JspWriter out=pageContext.getOut();
out.print("第"+currentNum+"次执行标签体。标签体执行完毕。
");
if(countNum>1){//如果还需要执行标签体
countNum--;
currentNum++;
return EVAL_BODY_TAG;
}else return SKIP_BODY;
}catch(Exception e){
System.out.println(e);
return SKIP_BODY;
}
}
//----标签结束时调用此方法-------
public int doEndTag(){
try{
JspWriter out=pageContext.getOut();
//----输出标签体的内容----
bodyContent.writeOut(bodyContent.getEnclosingWriter());
out.print("标签结束了。");
}catch(Exception e){
System.out.println(e);
}
return EVAL_PAGE;
}
public int getCountNum() {
return countNum;
}
public void setCountNum(int countNum) {
this.countNum = countNum;
this.currentNum=1;
}
}
执行标签体并不会直接输出标签体中的内容,因此本实例在doEndTag()方法中一次性把执行的结果输出。
(2)第二步:编写标签描述tld文件。
因为本章所有实例共用一个应用,故本例在myTag.tld文件中增加内容。在
对于属性countNum的声明中,
(3)第三步:在Web应用的.xml文件中声明标签库引用。
同样,本例与实例108使用同一个tld文件,不必再修改。
(4)第四步:在JSP页面中声明并调用标签。
UseBodyTag1.jsp
<%@ taglib uri="/myTag" prefix="myTag" %>
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="java.util.Date" %>
【实例111】 开发嵌套的标签:haveChildTag
(1)第一步:开发标签实现类。
内层的标签helloTag在实例108中已有,此处不再列出。
haveChildTag.java
package hello;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class haveChildTag extends BodyTagSupport {
private boolean isOutput;//是否输出子标签内容
//----标签开始时调用此方法-------
public int doStartTag(){
if(isOutput)
return EVAL_BODY_INCLUDE;
else return SKIP_BODY;
}
//----标签结束时调用此方法-------
public int doEndTag(){
try{
if(bodyContent!=null)
bodyContent.writeOut(bodyContent.getEnclosingWriter());
}catch(Exception e){
System.out.println(e);
}
return EVAL_PAGE;
}
public boolean getIsOutput() {
return isOutput;
}
public void setIsOutput(boolean isOutput) {
this.isOutput = isOutput;
}
}
(2)第二步:编写标签描述tld文件。
本例在myTag.tld文件中增加内容。在
(3)第三步:在应用的.xml文件中声明标签库引用。
同样,本例与本章前面的实例使用同一个tld文件,此处不必再修改。
(4)第四步:在页面中声明并调用标签。
useHaveChildTag.jsp
<%@ taglib uri="/myTag" prefix="myTag" %>
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="java.util.Date" %>
《JSP网络编程从实践到实践》原码地址:
五、 开发迭代的标签
【实例112】 开发迭代的标签:iterateTag
对于集合对象的Iterator类对象,在JSP的代码中需要用while循环或for循环来输出,难于维护,且可复用性不好,总是在大量地做这样的工作,这时可以考虑用迭代的标签来开发,需要输出数据时只须在JSP页面中声明标签即可。
开发迭代的标签,需要设计两个Java类:标签实现类和表示标签信息的类。本实例中标签实现类为iterateTag.java,表示标签信息的类为IterateTEI.java。开发迭代的标签可实现IterationTag接口,也可从TagSupport类或BodyTagSupport类继承,由于BodyTagSupport类继承自TagSupport类,而TagSupport类又实现了IterationTag接口,为简化开发,直接从BodyTagSupport类继承即可。
(1)第一步:开发标签实现类和表示标签信息的类。
iterateTag.java
package body;
import java.util.Collection;
import java.util.Iterator;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class iterateTag extends BodyTagSupport{
private String name;//在pageContext中标识的一个属性名
private Iterator it;//要迭代的对象
private String type;//it中对象的类型
public void setCollection(Collection collection){
if(collection.size()>0)
it=collection.iterator();
}
//----标签开始时调用此方法-------
public int doStartTag(){
if(it==null) return SKIP_BODY;
else return continueNext(it);
}
//----标签体执行完后调用此方法----
public int doAfterBody(){
return continueNext(it);
}
//----标签结束时调用此方法-------
public int doEndTag(){
try{
if(bodyContent!=null)
bodyContent.writeOut(bodyContent.getEnclosingWriter());
}catch(Exception e){
System.out.println(e);
}
return EVAL_PAGE;
}
//----迭代----
protected int continueNext(Iterator it){
if(it.hasNext()){
pageContext.setAttribute(name,it.next(),pageContext.PAGE_SCOPE);
return EVAL_BODY_TAG;
}else return SKIP_BODY;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
在标签实现类中,有3个属性:name、type和it。其中,name代表在pageContext中标识一个属性的名字;type代表待迭代内容的数据类型;it为要迭代的内容。在doStartTag()方法中,如果it不为null,就开始迭代,迭代时调用continueNext()方法。
IterateTEI.java
package body;
import javax.servlet.jsp.tagext.TagData;
import javax.servlet.jsp.tagext.TagExtraInfo;
import javax.servlet.jsp.tagext.VariableInfo;
public class IterateTEI extends TagExtraInfo {
public IterateTEI() {
super();
}
public VariableInfo[] getVariableInfo(TagData data){
return new VariableInfo[]{
new VariableInfo(data.getAttributeString("name"),
data.getAttributeString("type"),
true,VariableInfo.NESTED)
};
}
}
VariableInfo类中有几个常量,具体的含义为:
NESTED:标签中的参数在标签开始到标签结束之间是有效的。
AT_BEGIN:标签中的参数在标签开始到使用它的JSP页面结束是有效的。
AT_END:标签中的参数在标签的结束到使用它的JSP页面结束是有效的。
(2)第二步:编写标签描述tld文件。本例在myTag.tld文件中增加内容。在
(3)第三步:在Web应用的.xml文件中声明标签库引用。同样,本例与本章前面的实例使用同一个tld文件,因此不必再修改。
(4)第四步:在JSP页面中声明并调用标签。
<%@ taglib uri="/myTag" prefix="myTag" %>
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="java.util.ArrayList"%>