[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所需要注意到的事情。

前言

我們目前已經看過了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>

大部份的內容應該用看的就瞭解。有幾個比較特別:

  1. short-name:這個是建議的prefix名稱。例如在jstl裡面就是c
  2. body-content:總共有nonejsptagdependent。這個設定的是在我們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的內容也沒什麼用處,所以接下來我們會在介紹自定義相關內容。

Dotblogs 的標籤: ,

Google+

創用 CC 授權條款
Alan Tsai 的隨手筆記Alan Tsai製作,以創用CC 姓名標示 4.0 國際 授權條款釋出。