這個(gè)例子是在Eclipse3.1+MyEclipse4.1+Tomcat5.0的環(huán)境下運(yùn)行通過的。
本來,這個(gè)例子在網(wǎng)上可以搜到的,但是,在實(shí)驗(yàn)中卻通不過,什么也輸不出。我不知道作者有沒有實(shí)驗(yàn),還是其它原因。這里只列出正確的代碼,具體的說明可以在網(wǎng)上搜到。
完成功能:擴(kuò)展JSP,令它擁有自己的HTML編碼功能。這個(gè)功能將所有的<和>字符用 HTML代碼來代替。它可以很容易地?cái)U(kuò)展為做其它的編碼處理。為了簡(jiǎn)化,這個(gè)例子只解釋了建立自定義標(biāo)簽的基本要素。
在MyEclipse中建立一個(gè)Web工程。
創(chuàng)建JavaBean
代碼中的任何可重用部分都應(yīng)該放到一個(gè)JavaBean中。在這個(gè)例子中,為HTML編碼的邏輯是常用的,因此放到JavaBean中,請(qǐng)參看清單A
清單B:HTML編碼JavaBean
/* HTML_Format.java */
public class HTML_Format extends Object implements java.io.Serializable {
/** 創(chuàng)建新的HTML_Format */
public HTML_Format() {}
/** 將一個(gè)字符串中所有的所有 < 和 > 字符用響應(yīng)的HTML編碼代替 */
public String HTML_Encode(String as_data)
{
int li_len = as_data.length();
/*string buffer的長(zhǎng)度要比原來的字符串長(zhǎng)*/
StringBuffer lsb_encode = new StringBuffer(li_len + (li_len/10));
/* 循環(huán)替換全部的< 和 > 字符 */
for( int li_count = 0 ; li_count < li_len ; li_count++)
{
String ls_next = String.valueOf(as_data.charAt(li_count));
if (ls_next.equals("<")) ls_next = "<";
if (ls_next.equals(">")) ls_next = ">";
lsb_encode.append( ls_next );
}
return( lsb_encode.toString() );
}
}
標(biāo)簽處理器的代碼請(qǐng)參看清單B:
清單C:HTML編碼標(biāo)簽處理器 HTML_FormatTag.java
import java.io.IOException;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
public class HTML_FormatTag extends BodyTagSupport
{
/* 1) 在標(biāo)簽?zāi)?huì)調(diào)用這個(gè)函數(shù) */
public int doEndTag() throws JspTagException
{
try
{ /* 2)得到標(biāo)簽中的文本 */
BodyContent l_tagbody = getBodyContent();
String ls_output = "";
if(l_tagbody != null)
{ HTML_Format l_format = new HTML_Format();
/* 3a) 將標(biāo)簽體的內(nèi)容轉(zhuǎn)換為一個(gè)字符串 */
String ls_html_text = l_tagbody.getString();
ls_output = l_format.HTML_Encode(ls_html_text);
}
/* 4)將結(jié)果寫回到數(shù)據(jù)流中 */
System.out.println(ls_output);
pageContext.getOut().write(ls_output.trim());
}
catch (IOException e)
{ throw new JspTagException("Tag Error:" + e.toString());
}
/* 讓JSP繼續(xù)處理以下頁面的內(nèi)容 */
return EVAL_PAGE;
}
}
創(chuàng)建標(biāo)簽描述符
我們需要描述自定義標(biāo)簽以讓系統(tǒng)知道如何處理。該描述文件的后綴為.tld,TLD文件通常就以標(biāo)簽處理器命名,并存放在“/WEB-INF/”目錄之下。請(qǐng)?jiān)趀clipse的工程中在“/WEB-INF/”目錄上點(diǎn)右鍵,New-->File,即可,注意后綴名為.tld。請(qǐng)參看清單C。清單C:HTML編碼標(biāo)簽描述器HTML_FormatTag.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.2</jspversion>
<shortname>HTML_FormatTag</shortname>
<uri></uri>
<info>HTML Encoding Tag</info>
<tag>
<name>HTMLEncode</name>
<tag-class>tagtest.HTML_FormatTag</tag-class>
<body-content>tagdependent</body-content>
</tag>
</taglib>
更新Web XML文件
現(xiàn)在可以告訴JSP容器如何使用標(biāo)簽庫(kù)了。為此要修改web.xml文件,具體說來是要在其中加入一個(gè)taglib的項(xiàng)目來注冊(cè)該標(biāo)簽庫(kù),并為標(biāo)簽分配一個(gè)URI。示例代碼請(qǐng)參看清單D。清單D:修改web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
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
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<jsp-config>
<taglib>
<taglib-uri>HTMLEncode</taglib-uri>
<taglib-location>/WEB-INF/HTML_FormatTag.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
注意要加上jsp-config標(biāo)簽,否則在MyEclipse中報(bào)錯(cuò)誤的。
使用新的標(biāo)簽
自定義的標(biāo)簽設(shè)置好后,就可以用在你的JSP頁面上了。要做到這一點(diǎn),只需要在頁面上使用 taglib指示命令聲明所要采用的標(biāo)簽即可。標(biāo)簽通過其唯一的 URI被索引,然后被分配給一個(gè)名字空間前綴(prefix)。這一前綴并沒有什么特別的意義,只要它不與其它的名字空間沖突便可,可以任意。請(qǐng)參看以下 的清單E。
清單E:在一個(gè)JSP頁面上使用HTML編碼標(biāo)簽testtag.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="HTMLEncode" prefix="Examples" %>
<html>
<head>
<title>My JSF 'testtag.jsp' starting page</title>
</head>
<body>
This is a test.
<pre>
<Examples:HTMLEncode>
test:<Hello,this World>
</Examples:HTMLEncode>
</pre>
this is a test.
</body>
This is a test.
test:<Hello,this World>
This is a test.
最開始,我按照網(wǎng)上的教程,可是,這一句:pageContext.getOut().write(ls_output.trim());就是不輸出到JSP頁面上。
后來,我查看了JSP的源代碼,才發(fā)現(xiàn)其實(shí)已經(jīng)輸出到JSP頁面,但是被JSP頁面把<Hello,this World>作為了HTML標(biāo)簽(但是,它不是HTML標(biāo)簽),就在瀏覽器上展現(xiàn)不出來了。
于是,我在HTML_Format.java類中改動(dòng)了以下兩句話:
if (ls_next.equals("<")) ls_next = "<";
if (ls_next.equals(">")) ls_next = ">";
就成功得輸出了。