我們目前已經看過了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所需要注意到的事情。
前言
我們目前已經看過了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所需要注意到的事情。
自定義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("
hello world
"); } 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>
大部份的內容應該用看的就瞭解。有幾個比較特別:
- short-name:這個是建議的prefix名稱。例如在jstl裡面就是c
-
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的內容也沒什麼用處,所以接下來我們會在介紹自定義相關內容。