ITEEDU

SimpleTagSupport类别<jsp:attribute>

SimpleTagSupport类别顾名思义,就是可以处理一些简单的自订标签需求,它是在JSP 2.0之后新增的类别,对于一些简单的自订标签页求,您可以继承它来实作标签处理类别,而不用为了处理一些TagSupport、 BodyTagSuppourt类别中回传值的问题。

为了使用上的简单而降低了复杂性,另一方面就是SimpleTagSupport类别所处理的功能受了些限制,它只处理标签与本体,要不要显示本体文字取 决于您,对于标签之后的页面则不在SimpleTagSupport处理的范围之内(虽然您还是可以使用forward之类的方式来决定要不要显示之后的 页面,但直接实作TagSupport会更方便一些),另外SimpleTagSupport类别的本体文字不能设定为JSP,这也是使用 SimpleTagSupport上的一些限制。

尽管有了一些限制,对于简单的自订标签需求,使用SimpleTagSupport还是比较容易的,它实作了SimpleTag接口,您只要重新定义 doTag()方法就可以实作自订标签的处理,先来看一个简单的范例:

SimpleHelloTag.java
package onlyfun.caterpillar;

import java.io.*; 
import javax.servlet.jsp.*; 
import javax.servlet.jsp.tagext.*; 

public class SimpleHelloTag extends SimpleTagSupport { 
public void doTag() throws JspException, IOException { 
JspWriter out = getJspContext().getOut(); 
out.println("Hello!World!"); 
} 
} 

假设在tld档中设定是这样的:

hello.tld
...
<tag> 
<description>Simple Tag</description> 
<name>hello</name>

<tag-class>onlyfun.caterpillar.SimpleHelloTag</tag-class> 
<body-content>empty</body-content> 
</tag> 
... 

则我们就可以在JSP网页中这么使用以显示一段Hello!World!文字:

<caterpillar:hello/>

 当然要真正显示字符串,别忘了web.xml中的设定与taglib的设定,前面已经说过好多次,不再重复了。


SimpleTagSupport预设不显示本体文字,如果您想要自订可以显示本体文字的卷标,则可以这么撰写:

SimpleTextTag.java
package onlyfun.caterpillar;

import java.io.*; 
import javax.servlet.jsp.*; 
import javax.servlet.jsp.tagext.*; 

public class SimpleHelloTag extends SimpleTagSupport { 
public void doTag() throws JspException, IOException { 
JspFragment frag = getJspBody(); 
frag.invoke(null); 
} 
} 

getJspBody()方法传回JspFragment对象,它包括了卷标本体的相关讯息,使用invoke()方法可以将这些讯息写入指定的 Writer中,如果设定为null,则预设写入getJspContext().getOut()取得的Writer,假设 tld档是这样设定:

text.tld
...
<tag> 
<description>Simple Tag</description> 
<name>showbody</name> 
<tag-class>demo.tags.SimpleTagText</tag-class> 
<body-content>tagdependent</body-content> 
</tag> 
... 

则可以在JSP网页中这么使用它,作用只是将本体文字再显示出来:

<caterpillar:showbody>

显示这段文字。。。。

</caterpillar:showbody>

除了使用上面的方式来包装本体文字至JspFragment中之外,您还可以< jsp:attribute>动作元素,将指定的文字包装为JspFragment,例如先撰写以下的标签处理类别:

SimpleFragTag.java
package onlyfun.caterpillar; 

import java.io.*; 
import javax.servlet.jsp.*; 
import javax.servlet.jsp.tagext.*; 

public class SimpleFragTag extends SimpleTagSupport { 
private JspFragment fragment1; 
private JspFragment fragment2; 

public void setFragment1(JspFragment fragment1) { 
this.fragment1 = fragment1; 
} 

public void setFragment2(JspFragment fragment2) { 
this.fragment2 = fragment2; 
} 

public void doTag() throws JspException, IOException { 
fragment2.invoke(null); 
fragment1.invoke(null); 
} 
} 

这个处理类别将接受两个JspFragment,为了要能包装JspFragment,必须在tld檔中指定:

frag.tld
...
<tag> 
<description>Simple Tag</description> 
<name>fragtest</name> 
<tag-class>onlyfun.caterpillar.SimpleFragTag</tag-class> 
<body-content>empty</body-content> 
<attribute> 
<name>fragment1</name> 
<required>true</required> 
<fragment>true</fragment> 
</attribute> 
<attribute> 
<name>fragment2</name> 
<required>true</required> 
<fragment>true</fragment> 
</attribute> 
</tag> 
... 

这次在设定属性时,指定<fragment>为true,表示属性将接受JspFragment对象,接下来这样测试:

test.jsp
<%@taglib prefix="caterpillar" 
uri="http://caterpillar.onlyfun.net/"%> 
<html> 
<body>
<caterpillar:fragtest> 
<jsp:attribute name="fragment1"> 
Frag1 Test ..... <br> 
</jsp:attribute> 
<jsp:attribute name="fragment2"> 
Frag2 Test .... <br> 
</jsp:attribute> 
</caterpillar:fragtest>
</body> 
</html> 

这个JSP网页的传回结果如下:

<html> 
<body> 
Frag2 Test .... <br>Frag1 Test ..... <br> 
</body> 
</html> 
如果您想要处理卷标的本体文字内容的话该怎么办呢?invoke()方法可以将文字写入指定的Writer中,可以使用StringWriter,将文字写入当中,然后再取得String对象就可以进行处理了,例如:

SimpleDemoTag.java
package onlyfun.caterpillar;

import java.io.*; 
import javax.servlet.jsp.*; 
import javax.servlet.jsp.tagext.*; 

public class SimpleDemoTag extends SimpleTagSupport { 
public void doTag() throws JspException, IOException { 
JspFragment frag = getJspBody(); 
JspWriter out = getJspContext().getOut(); 
StringWriter writer = new StringWriter(); 

frag.invoke(writer); 
String str = writer.toString(); 
out.println(str.replaceAll("<%","<%")); 
} 
} 

上面的程序示范了如何处理本体文字,这个卷标处理类别将所有的 <% 置换 &lt;。