JSP自定義标記為在動态 Web 頁中将頁面表示與業務邏輯分離提供了一種标準化的機制,使頁面設計者可以将注意力放到頁面表示上,而應用程式開發人員則專注于編寫後端的代碼。您可能聽說現在有上百種不同的方式,但是在開發 Web 應用程式時将表示邏輯與業務邏輯分離是很重要的。近年來,Java 平台已經發展為在體系結構層次上加入了這種分離。例如,在 JSP 體系結構中加入 JavaBean 元件使開發人員使用 JSP 标記獲得和設定經過特别編碼的 java 元件上的屬性。這些元件或者 JavaBean 再代表表示層執行後端業務處理。
JSP 自定義标記是 JSP/JavaBean 體系結構的産物。像 JavaBean 技術一樣,自定義标記有助于将表示邏輯與業務邏輯分離。并且自定義标記成了 Web 設計者的 HTML、XML 和 Javascript 世界與軟體工程師的 Java 代碼、SQL 調用和算法世界之間的橋梁。
JSP 自定義标記
JSP 自定義标記 是使用者定義的标記,它遵循 JSP JavaBean 标記(即 useBean、getProperty 和 setProperty)所使用的一種特殊的 xml 文法。當 servlet 容器處理自定義标記時,會調用一個或者多個 Java 類檔案處理它,與用 Java 類檔案處理 JSP 頁面的 JavaBean 調用的方式基本一樣。處理标記以後,容器将取其名字和屬性、以及标記正文中可能有的任何内容,并将它傳遞給一個或者多個類檔案進行處理。
Java 開發人員編寫标記處理程式類以處理标記并處理所有需要的 Java 代碼和資料操作。對于 Web 設計者來說,自定義标記與标準 html 标記除了都可以利用後端動态資料外,它們看上去與使用起來沒什麼差別。正确編寫自定義标記可以讓 Web 設計者建立、查詢和操作資料而無需編寫一行 Java 代碼。正确使用自定義标記使 Java 開發人員不必再在編碼過程中考慮表示層。這樣應用程式開發小組的每一位成員都可以關注于他或者她最擅長的事物。
實作 JSP 自定義标記
JSP 體系結構需要以下元件以實作自定義标記:
在每一頁中有一個 JSP 聲明
Web 應用程式描述符(web.xml)中的一個項
一個包含特殊 XML 檔案和為處理自定義标記而調用的 Java 類的 JAR 檔案
要想成功實作 JSP 自定義标記,您需要采取下面四個步驟:
編寫标記處理程式類。
建立标記庫描述符(TLD)。
引用标記庫。
在 JSP 頁面中使用标記。
那我們就以經典的"Hello,World"開始吧。。。
第 1 步. 編寫标記處理程式類
我們要做的第一件事是編寫标記處理程式類。在執行引用自定義标記的 JSP 頁面時,JSP 容器判斷每一個自定義标記。當容器遇到一個标記時,它調用與這個自定義标記相關聯的标記處理程式,我們将在後面更多地讨論這個過程。然後,每一個标記處理程式實作 JSP API中的一個特殊接口。标記有兩種類型:可以處理标記内容(或者正文)的标記和不能處理标記内容的标記:
<abc:tagWithNoBody attribute="value"/>
<abc:tagWithBody attribute="value">
This is some body content that the tag handler can operate upon.
</abc:tagWithBody>
在 例子中不需要加入正文内容,因為它隻顯示一個字元串。是以,我們的處理程式類将實作 Tag 接口(一般是通過擴充 TagSupport 類)。如果我們要建立一個可以處理正文的标記,那麼我們就需要實作 BodyTag 接口(一般是通過擴充 BodyTagSupport 類)。
清單 1. 标記處理程式類
package com.vitamin.taglib;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag implements Tag
{
private PageContext context = null;//頁面上下文
public HelloTag()
{
super();
// TODO 自動生成構造函數存根
}
public void setPageContext(PageContext pageContext)
this.context = pageContext;
public void setParent(Tag tag)
public Tag getParent()
return null;
public int doStartTag()throws JspException
try
{
this.context.getOut().println("hello,world");
}
catch(IOException ex)
throw new JspException(ex.getMessage());
return Tag.SKIP_BODY;
public int doEndTag()
return Tag.SKIP_PAGE;
public void release()
}
當然在這裡值得注意的是,我這是采用了實作Tag接口的方法來做的,其實更好的方式是繼承自TagSupport類。因為 TagSupport 類是簡單的、具體類,它完全實作了在 Tag 接口中聲明的方法,我們可以隻實作那些在自定義标記中要使用的方法。
第 2 步. 建立 TLD
下一步是定義包含自定義标記與處理它的 Java 類(或多個類)之間的映射的庫。這個庫是在一個名為标記庫描述符(TLD)的 XML 文檔中定義的。
清單 2. mytag.tld 檔案
<?xml version="1.0" encoding="UTF-8"?>
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>hello</shortname>
<tag>
<name>sayHello</name>
<tagclass>com.vitamin.taglib.HelloTag</tagclass>
<bodycontent>empty</bodycontent>
</tag>
</taglib>
所有關鍵資訊都包含在 Tag 标記中,在這裡映射了标記名和處理程式類,我們聲明了标記對于正文内容的敏感性。對于更複雜的情況,我們可以使用其他的 XML 标記以提供有關庫和标記的更多資訊。在一個庫中定義多個标記也很常見。
第 3 步. 引用這個标記庫
有兩種方法聲明 JSP 頁面與其庫之間的引用。可以通過 Web 應用程式描述符(web.xml)聲明一個靜态引用,也可以直接在頁面中聲明一個動态引用。(可奇怪的是,我在用靜态引用時,居然失敗,web.xml裡面放進去聲明時就會報錯。。。)
為了進行動态引用,隻需在所有需要使用這個庫的頁面中加入一個 JSP 聲明即可:
<%@ taglib uri="/WEB-INF/mytag.tld" prefix="hello" %>
靜态引用與動态引用的比較
在進行标記庫的靜态引用時,JSP 聲明必須查詢 web.xml 檔案以執行庫查詢。這意味着如果移動或者重命名了庫,或者希望在 web.xml 檔案中加入更多的庫,就必須停止伺服器、更新 web.xml 檔案、然後重新啟動伺服器。動态方法讓 JSP 頁直接指向 TLD 位置,因而是在解釋 JSP 頁面時進行處理。
靜态方法提供了頁面與庫的實際名和位置之間一定程度的非直接性,這可以為您提供一些改變這些屬性而不修改頁面的靈活性。另一方面,動态方法提供了更大的靈活性,讓您可以在運作時增加和移動标記聲明。如果您對動态方法感興趣,但是又擔心做了一些改變後、有可能要更新多個頁面的維護負擔,那麼您可以始終将 JSP 聲明放到一個單獨的 JSP 檔案中,并在每一個要通路 Web 應用程式的自定義庫的頁面中加入這一頁。這使您具有在運作時隻需要更新資訊一次就可以增加庫的靈活性。
第 4 步. 在 JSP 頁面中使用标記
完成了所有這些準備工作後,我們就可以在 JSP 頁面中使用這些自定義标記了。
清單 3. 帶有自定義标記的 JSP 頁
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<hello:sayHello/>
</body>
</html>
用JSTL 節省時間
您所需要的自定義标記功能中也許有多達百分之八十已經由 J2EE 團體建立并标準化了。使用現有的标記庫而不是從頭建立所有東西會使您節省大量時間和精力。盡管在公共域有數十種庫,不過業界彙集了一個特定的自定義庫。Java 标準标記庫(JSTL)是由 Java Community Process 設計的,其參考實作是由 Apache Group 通過 Jakarta Taglibs 項目所開發和維護的.
JSTL 定義了針對常見 Web 應用程式處理需求,如變量支援、流程控制、URL 管理、XML 操作、國際化、資料庫通路等等的标記。除了一組豐富的标記外,JSTL 還定義了自己的表達式語言(EL)。EL 使我們可以容易地通路應用程式資料并更容易在不使用腳本或者請求時表達式的條件下操作這些資料。
除了節省您從頭開發所有标記的時間和精力,JSTL 還具有标準化和業界承認的所有好處。這些好處包括廠商支援、大量介紹文字、以及有很大的機會找到具有 JSTL 經驗的雇員或者承包商。
結束語
在 J2EE Web 開發中越來越多地需要将業務和表示邏輯分離,JSP 自定義标記提供了替代簡單的老 JavaBean 和 Java 腳本的一個有吸引力的方法。更好的是在 JSTL 中已存在一組已定義的标準的自定義标記庫。
另外,标記庫技術雖然解決了java代碼和html混合的問題,但卻帶來了另一個問題,就是使用了标記庫的頁面不能進行可視化設計了!!!因為開發工具根本不能運作你背景的代碼,是以就顯示不出來頁面的結果了。于是,JSF就出現了。它一改以往的基于Web的Request-Response處理機制,而是采用了類似Swing的的事件驅動處理機制。它簡化了Web表單的有效性驗證,Request參數解析,狀态管理和多線程支援等任務,我們隻需要實作具體的事件處理子產品和事件邏輯子產品就可以了。
本文轉自Phinecos(洞庭散人)部落格園部落格,原文連結:http://www.cnblogs.com/phinecos/archive/2006/06/25/435236.html,如需轉載請自行聯系原作者