转载

JSP TAG开发

demo下载:test-tag.zip

开始学jsp的时候觉得jstl很酷炫,很神秘,还经常因为jar包找不到而沮丧,工作之后发现很多项目都有自定义tag库,tag库用的好,确实能减少service层的复杂性,通过查阅资料,对其有了一定的了解,将其写出来,共哪些对这个主题感兴趣的同学借鉴,

java自带的tag库的层级如下

JSP TAG开发

1、简单tag功能开发

如果只是简单的处理,可以继承自SimpleTagSupport,重载doTag()方法,先来个HelloTag.java

public class HelloTag extends SimpleTagSupport { private String name; @Override public void doTag() throws JspException, IOException { JspWriter writer = this.getJspContext().getOut(); writer.write("hello " + name); } public void setName(String name) { this.name = name; } }
public class HelloTag extends SimpleTagSupport { private String name; @Override public void doTag() throws JspException, IOException { JspWriterwriter = this.getJspContext().getOut(); writer.write("hello " + name); } public void setName(String name) { this.name = name; } } 

如果你的tag需要支持属性,比如HelloTag中的name属性,那么需要为其添加一个setter方法。doTag()的实现也很简单,获取JspWriter,向页面输出”hello ” + name内容。接下来需要创建一个.tld的描述文件,内容如下:

<?xml version="1.0" encoding="UTF-8" ?>  <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <short-name>Example TLD with Body</short-name> <uri>http://javacoder.cn/jsp/jtag</uri>  <tag> <name>hello</name> <tag-class>cn.javacoder.test.tag.HelloTag</tag-class> <body-content>empty</body-content> <attribute> <name>name</name> <rtexprvalue>false</rtexprvalue> <required>true</required> <description> <![CDATA[ this is a hello test ]]> </description> </attribute> </tag> </taglib>
<?xmlversion="1.0" encoding="UTF-8" ?>   <taglibxmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <short-name>ExampleTLDwithBody</short-name> <uri>http://javacoder.cn/jsp/jtag</uri>   <tag> <name>hello</name> <tag-class>cn.javacoder.test.tag.HelloTag</tag-class> <body-content>empty</body-content> <attribute> <name>name</name> <rtexprvalue>false</rtexprvalue> <required>true</required> <description> <![CDATA[ this is a hellotest ]]> </description> </attribute> </tag> </taglib> 

大家也不必强记这个文件格式,在<%@ taglib prefix=”fmt” uri=”http://java.sun.com/jsp/jstl/fmt”%> 处,”ctrl+鼠标左键”可以查看该tag库的tld,然后依猫画虎啦。

这个tld文件其实就是一个xml文件,引入web-jsptaglibrary_2_0.xsd是为了内容验证,当然uri也可以不加的。rtexprvalue表示值的内容是否为表达式,比如el表达式。

接下来创建一个test.jsp,添加内容如下:

<%@ taglib prefix=”ex” uri=”/WEB-INF/classes/custom.tld”%>

<ex:hello name=”javacoder.cn”/>

第一行代码的作用是导入我们的标签库,第二行是调用我们的tag。

部署到服务器,访问这个页面,那么会向页面输出”javacoder.cn”

2、实现稍微复杂的tag功能

这就是TagSupport和BodyTagSupport抽象类大显身手的时候了。

TagSupport中几个重要的,需要我们根据实际的业务重载的方法如下:

public int doStartTag() throws JspException

标识tag处理开始,处理流程和在doTag()方法中一样,获取Writer,向页面输出内容。如果需要处理tag的boby部分,就是这个tag有包含的内容,那么返回EVAL_BODY_INCLUDE否则返回SKIP_BODY。

public int doEndTag() throws JspException

标识一个tag处理结束。合法的返回值是EVAL_PAGE和SKIP_PAGE。一般当包含子tag的时候,才需要实现doEndTag()方法,比如当然tag输出table元素,那么在子元素处理完成后,需要在这个方法中输出”</table>”这样的结束元素。

public int doAfterBody() throws JspException

当doStartTag方法返回EVAL_BODY_BUFFERED时,tag的处理流程如下。

当doStartTag()执行完成后,会创建一个bodyContent对象,然后,处理该tag包含的子元素,当子元素处理完成后,会调用doAfterBody方法,如果doAfterBody返回 EVAL_BODY_AGAIN,那么会再次处理子元素,如果返回SKIP_BODY那么调用doEndTag(),结束本tag的处理。这个可以参考core标签库的c:forEach的实现。

BodyTagSupport类继承自TagSupport,一个重要的扩展是我们可以高效地处理tag的body内容。这个基类的一个重要扩展是添加了bodyContent。demo中的cn.javacoder.test.tag.LoopTag虽然有点无聊,但是也是对这个功能的一个演示。

本demo还实现了另外的两个标签,TableTag, TrTag,用来演示el表达式的使用。欢迎下载

本文由javacoder.cn博主提供,转载请注明出处!

Posted in:WEB开发

原文  http://www.javacoder.cn/?p=686
正文到此结束
Loading...