在JSP編程中,Struts一般用來處理form和業(yè)務(wù)邏輯,Struts中使用了很多自定義標(biāo)簽,如html、bean等,但很多時候我們還是需要使用 "<% java code %>" 這樣的語句來操作一些輸出。為了減少這種代碼,可以創(chuàng)建自定義標(biāo)簽。
一個tag就是一個普通的java類,它唯一特別之處是它必須繼承TagSupport或者BodyTagSupport類。這兩個類提供了一些方法,負(fù)責(zé)jsp頁面和你編寫的類之間的交互,例如輸入,輸出。而這兩個類是由jsp容器提供的,無須開發(fā)人員自己實(shí)現(xiàn)。換句話說,你只需把實(shí)現(xiàn)了業(yè)務(wù)邏輯的類繼承TagSupport或者BodyTagSupport,再做一些特別的工作,你的類就是一個Tag。并且它自己負(fù)責(zé)和jsp頁面的交互,不用你多操心。
下面介紹如何創(chuàng)建一個自定義標(biāo)簽。
一.編寫java類繼承TagSupport或TagSupport 1) 提供屬性的set方法, 此后這個屬性就可以在jsp頁面設(shè)置。以jstl標(biāo)簽為例 <c:out value=""/>,這個value就是jsp數(shù)據(jù)到tag之間的入口。所以tag里面必須有一個setValue方法,具體的屬性可以不叫value。例如setValue(String data){this.data = data;}
這個“value”的名稱是在tld里定義的。取什么名字都可以,只需tag里提供相應(yīng)的set方法即可。
2)處理 doStartTag 或 doEndTag 這兩個方法是 TagSupport提供的。 還是以<c:out value=""/>為例,當(dāng)jsp解析這個標(biāo)簽的時候,在“<”處觸發(fā) doStartTag 事件,在“>”時觸發(fā) doEndTag 事件。通常在 doStartTag 里進(jìn)行邏輯操作,在 doEndTag 里控制輸出。
下面是一個簡單的例子
- package com.test.tag;
- import java.io.IOException;
- import javax.servlet.jsp.JspTagException;
- import javax.servlet.jsp.tagext.BodyContent;
- import javax.servlet.jsp.tagext.BodyTagSupport;
-
-
-
- public class PermissionBodyTag extends BodyTagSupport {
- boolean permission;
- public boolean isPermission() {
- return permission;
- }
- public void setPermission(boolean permission) {
- this.permission = permission;
- }
- public int doStartTag() throws JspTagException {
- if (permission) {
- return EVAL_BODY_INCLUDE;
- } else {
- return SKIP_BODY;
- }
- }
- public int doEndTag() throws JspTagException {
- System.out.println("doEndTag");
- try {
- if (bodyContent != null) {
- bodyContent.writeOut(bodyContent.getEnclosingWriter());
- }else{
- }
- } catch (IOException e) {
- throw new JspTagException("IO ERROR:" + e.getMessage());
- }
- return EVAL_PAGE;
- }
- public void doInitBody() throws JspTagException {
- }
- public void setBodyContent(BodyContent bodyContent) {
- this.bodyContent = bodyContent;
- }
- }
package com.test.tag;import java.io.IOException;import javax.servlet.jsp.JspTagException;import javax.servlet.jsp.tagext.BodyContent;import javax.servlet.jsp.tagext.BodyTagSupport;/*** PermissionBodyTag 根據(jù)是否有權(quán)限顯示body內(nèi)容*/public class PermissionBodyTag extends BodyTagSupport {boolean permission;public boolean isPermission() {return permission;}public void setPermission(boolean permission) {this.permission = permission;}public int doStartTag() throws JspTagException {if (permission) {return EVAL_BODY_INCLUDE;} else {return SKIP_BODY;}}public int doEndTag() throws JspTagException {System.out.println("doEndTag");try {if (bodyContent != null) {bodyContent.writeOut(bodyContent.getEnclosingWriter());}else{}} catch (IOException e) {throw new JspTagException("IO ERROR:" + e.getMessage());}return EVAL_PAGE;}public void doInitBody() throws JspTagException {}public void setBodyContent(BodyContent bodyContent) {this.bodyContent = bodyContent;}}
通常你會發(fā)現(xiàn)自己絕大多數(shù)活動都集中在 doStartTag 或 doEndTag 方法里。確實(shí)如此,熟悉一些接口和類之后,寫taglib很容易。正如《jsp設(shè)計(jì)》的作者所言:里面的邏輯稍微有點(diǎn)復(fù)雜,但畢竟沒有火箭上天那么難。
二.編寫tld文件 標(biāo)簽文件其實(shí)只是一個XML格式的說明文件,內(nèi)容也很簡單。
創(chuàng)建tagTest-html.tld文件在這個標(biāo)簽文件中,我們將我們創(chuàng)建的標(biāo)簽取名 tagTest,并聲明了類型和參數(shù)(permission)。將該文件保存在 /WEB-INF 下面。
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
- <taglib>
- <tlibversion>1.2</tlibversion>
- <jspversion>1.1</jspversion>
- <shortname>tagTest</shortname>
- <uri>/taiji</uri>
- <tag>
- <name>permission</name>
- <tagclass>com.test.tag.PermissionBodyTag</tagclass>
- <bodycontent>JSP</bodycontent>
- <attribute>
- <name>permission</name>
- <required>true</required>
- <rtexprvalue>true</rtexprvalue>
- </attribute>
- </tag>
- </taglib>
-
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"><taglib><tlibversion>1.2</tlibversion><jspversion>1.1</jspversion><shortname>tagTest</shortname><uri>/taiji</uri><tag><name>permission</name><tagclass>com.test.tag.PermissionBodyTag</tagclass><bodycontent>JSP</bodycontent><attribute><name>permission</name><required>true</required><rtexprvalue>true</rtexprvalue></attribute></tag></taglib>
三.加到web.xml中 當(dāng)然,我們還需要將我們自定義的標(biāo)簽添加到 web.xml 中,否則還是無法使用。
- <taglib>
- <taglib-uri>/tagTest </taglib-uri>
- <taglib-location>/WEB-INF/tagTest-html.tld</taglib-location>
- </taglib>
<taglib><taglib-uri>/tagTest </taglib-uri><taglib-location>/WEB-INF/tagTest-html.tld</taglib-location></taglib>
四.在jsp頁面導(dǎo)入tld
- <%@ taglib uri="/tagTest " prefix="tagTest "%>
<%@ taglib uri="/tagTest " prefix="tagTest "%>
這樣,你的jsp頁面就可以使用自己的tag了。用這個標(biāo)簽就可以根據(jù)傳人的boolean值來決定標(biāo)簽包的jsp內(nèi)容是否輸出
- <tagTest:permission permission="<% java code%>">
-
- </tagTest:permission>
<tagTest:permission permission="<% java code%>">//需有權(quán)限輸出,用戶才能看到的內(nèi)容</tagTest:permission>
優(yōu)點(diǎn)
1. 修改后的JSP文件不再或盡量少包含java代碼,. html代碼變得非常干凈,頁面設(shè)計(jì)人員修改頁面文件時,不用擔(dān)心誤刪除程序代碼了。
2. 程序開發(fā)人員使用簡單的空白頁就可以進(jìn)行開發(fā),待頁面設(shè)計(jì)人員提交目標(biāo)頁后,只需簡單的編輯即可完成替換
最終使頁面和代碼盡量分離。