我們目前已經看過了JSTL裡面的3個Tag。其實JSTL裡面還有兩個Tag,一個是用來處理XML的Tag,讓你可以對一個XML做類似于XPath的動作。還有一個是對資料庫做動作的tag。
這兩個Tag我跳過了,首先對DB可以做存取的Tag我覺的不應該是JSP頁面做的事情,而是Servlet做。因此我覺的只要知道有這個Tag就好,我個人會儘量不用。至於XML的tag有用,但是其實他和之前介紹core tag非常像,只是在Select是使用類似于xpath的概念去parse xml。因此,如果有需要在去看就可以。
今天,我希望來介紹一下基本自定義Tag所需要注意到的事情。
(和我部落格同時發佈:http://www.dotblogs.com.tw/alantsai/archive/2013/10/16/tag-intro.aspx)
自定義Tag
看完了JSTL或許你開始只想用JSTL在jsp裡面,而不想穿插一些Scriptlet。但是雖然jstl提供很多功能,在真的使用的時候應該會發現不夠,這些功能都不夠。
畢竟每一個專案的需求不同,當我們需要使用特別的邏輯的時候怎麼辦?
其實每一個tag都只是一個java class而已。java class裡面定義每一個tag會做什麽,而同時用tld檔案(Tag Library Descriptor 的縮寫)來定義有哪些tag可以使用。
tag是從jsp 1.x版本開始就有了,而到了jsp 2.x除了能夠兼容1.x的tag之外,還增加了一些東西讓寫tag變得更容易。我們會先從jsp 1.x的看起,瞭解了本質,再來學習新的會更加容易理解。
自定義標籤hello world
tag的作用就是封裝常用的程式片段,我們會先寫一個hello world的tag來瞭解如何寫出一個自定義的tag。
首先,我們提到tag其實就是普通的java class,至於爲什麽它是tag是因為它們都需要實作 javax.servlet.jsp.tagext.Tag。
Tag interface其實定義了一些方法,而這些方法會在處理tag的時候被觸發。下面是一個hello world的tag範例:
public class HelloWorld implements Tag {
private Tag parent;
private PageContext context;
//要離開Tag的時候要執行的
@Override
public int doEndTag() throws JspException {
JspWriter out = context.getOut();
try {
out.println("<p>hello world </p>");
} catch (IOException e) {
e.printStackTrace();
}
return EVAL_PAGE;
}
//進入Tag的時候要執行的
@Override
public int doStartTag() throws JspException {
return SKIP_BODY;
}
//取得此tag的父tag
@Override
public Tag getParent() {
return parent;
}
//釋放資源
@Override
public void release() {
}
//assign代表jsp的context
@Override
public void setPageContext(PageContext arg0) {
context = arg0;
}
//assign代表進入到此tag之前的tag
@Override
public void setParent(Tag arg0) {
parent = arg0;
}
}
每一個method在做什麽我都已經有注解了,其實對我們來說重要的是doEndTag()和doStartTag()。至於這些方法所回傳的int代表什麽,在之後我們介紹tag的lifecycle 會在提到。
定義tld檔案
在我們的function定義好了之後,我們接下來需要定義tld檔案,告知系統目前有哪些tag可以使用。
可以透過增加xml檔案的方式放在WEB-INF下面即可,下面就是我的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/web-
jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<jsp-version>1.1</jsp-version>
<short-name>hello</short-name>
<uri>http://www.hello.com/tags</uri>
<info>this is my test</info>
<tag>
<name>test</name>
<tag-class>tag.HelloWorld</tag-class>
<body-content>JSP</body-content>
</tag>
</taglib>
大部份的內容應該用看的就瞭解。有幾個比較特別:
1 short-name:這個是建議的prefix名稱。例如在jstl裡面就是c
2 body-content:總共有none、jsp和tagdependent。這個設定的是在我們tag裡面是否可以有別的tag。 none表示不可以,jsp表示可以並且可以輸入jsp代碼。tagdependent可以但是不會執行jsp代碼。
假設我們tld檔案不是放在WEB-INF/下面,那麼就需要把tld的位置放在web.xml裡面,例如:
<jsp-config>
<taglib>
<taglib-uri>http://www.hello.com/tags</taglib-uri>
<taglib-location>/WEB-INF/Tags/HelloWrold.tld</taglib-location>
</taglib>
</jsp-config>
這邊假設我們tld放在WEB-INF/tags/裡面,那麼就需要設定。
在jsp頁面使用我們自定義的tag
在jsp裡面要使用,就是:
<%@ taglib uri="http://www.hello.com/tags" prefix="hello" %>
<hello:test />
假設我們今天tld不在WEB-INF下面,也沒有在web.xml定義,那麼可以透過URI的方式指定路徑:
<%@ taglib uri="WEB-INF/tags/HelloWorld.tld" prefix="hello" %>
結語
透過這一篇,希望大家對於如何建立一個tag比較瞭解。不過只能夠建立static的內容也沒什麼用處,所以接下來我們會在介紹自定義相關內容。