Struts
提供了一個強大的
HTML
標簽庫來幫助你構建
Web
應用程序。
為了更容易、更快速地進行開發,
Struts
提供了功能同其它
JSP
標簽庫類似的五個標簽庫,即:
HTML
、
Bean
、
Logic
、
Template
和
Nested
。第一部分講述如何配置一個
Struts
應用程序來運用這個標簽庫,并介紹了第一組標簽;第二部分講述了第二組標簽;
?
HTML
標簽庫主要用來顯示
HTML
元素,如果不用這種方法,你就必須用
HTML
標簽來指定它們。從表面上看,這個標簽庫很簡單。但是通過深入研究,我們就會發現它很強大。例如,它可以為我們在
HTML
表單的一個特定輸入元素中放置重點內容生成
JavaScript
,或為客戶端輸入驗證生成腳本。而且,你可以用它通過一行代碼來處理錯誤。然而,在將這個標簽庫用于你的
Struts
應用程序前,你需要做些簡單的準備工作。
配置應用程序來運用標簽庫
在運用
Struts HTML
標簽庫前,你需要通過三個步驟來配置一個
Struts
應用程序。
1.?????
在部署描述符(
web.xml
文件)中注冊標簽庫:
? <taglib>
??? <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
??? <taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
上面的代碼就告訴了
servlet container
有關
Struts HTML
標簽庫的情況,以及在哪里可以找到標簽庫的
TLD
文件。
2.
確信將
struts-html.tld
文件復制到
WEB-INF
目錄中。你不用擔心標簽庫類文件,因為它們已經包含在
struts.jar
文件中了。
3.
在運用標簽庫的每個
JSP
頁面中,插入下面的
<taglib>
指示符:
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
另外,你也可以運用
struts-html.tld
文件來學習它所支持的標簽以及每個標簽可以帶有哪些屬性。
運用一個自定義的標簽庫通常是很容易的:只要遵循前面講述的步驟就行了。然而,有些標簽庫包含一些原則,這些原則使我們在運用這些標簽庫時并不那么容易。
Struts HTML
標簽庫就是其中之一。有些標簽很簡單、很容易使用;然而,另外有些標簽則取決于
Struts
應用程序中的其它標簽或其它元素。
我將
HTML
標簽庫中的標簽大致分成了兩類:簡單、容易使用的標簽,我把它們稱為
“
獨立的標簽
”
,第二類是必須通過一個
form
標簽來使用的標簽。我把第二類的標簽簡單地稱為與
form
相關的標簽。本文主要講述獨立的標簽,在本系列文章的
第二部分
我將講述與
form
相關的標簽。
HTML
標簽庫包含幾個很容易使用的獨立的標簽。下面講述幾個比較重要的標簽。
<html>
標簽
<html>
標簽是
HTML
標簽庫中最容易的標簽。它有兩個屬性:
locale
和
xhtml
,兩者都不是必需的。下面的代碼選自一個運用
<html>
標簽的
JSP
頁面:
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html:html locale="true">
<head>
<title>Welcome</title>
</head>
<body>
Hello World!
</body>
</html:html>
注意,我們沒有用標準的
<html>
元素,而是用了
<html:html>
標簽。其中第一個
html
指的是前綴,第二個是
<html>
標簽本身。而且我們也用了
locale
屬性。
JSP
頁面將顯示成:
<html lang="en">
<head>
<title>Welcome</title>
</head>
<body>
Hello World!
</body>
</html>
注意,
<html:html locale=“true”>
中的
locale
屬性在生成的
HTML
頁面中被轉換成了
lang=“en”
。生成的結果取決于
Struts
應用程序所位于的服務器的
locale
。如果你將應用程序部署到一個不同
locale
的服務器,你不需要改變代碼。
Locale
會自動調整。
<base>
標簽
<base>
標簽顯示一個
HTML
元素,用一個
href
屬性表示所包含的
JSP
頁面的絕對位置。只有當這個標簽是內嵌在一個
head
標簽部分時,它才有效。例如這個
JSP
頁面:
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html:html locale="true">
<head>
<title>Welcome</title>
<html:base/>
</head>
<body>
Hello World!
</body>
</html:html>
會轉換成以下形式:
<html lang="en">
<head>
<title>Welcome</title>
<base >
</head>
<body>
Hello World!
</body>
</html>
<img>
標簽
<img>
標簽用來生成一個
HTML <IMG>
標簽。它最重要的屬性有:
·page
:圖象文件相對于模塊的路徑;前面必須帶有一個斜線
·height
:圖象的高度
·width
:圖象的寬度
·alt
:如果找不到圖象,顯示的文本
例如:
<html:img page="/logo.gif" height="50" width="200" alt="Company Logo"/>
會轉換成:
<img src="/myStrutsApp/logo.gif" height="50" width="200" alt="Company Logo">
<link>
標簽
<link>
標簽會生成一個超鏈接。例如標簽:
<html:link page="/index.html">Click here</html:link>
會轉換成:
<a href="/myStrutsApp6/index.html">Click here</a>
<errors>
標簽
<errors>
標簽的易于使用性通常會掩蓋其真正的強大功能。通過一個簡單的
<html:errors/>
標簽,你就可以在一個
JSP
頁面上顯示完全自定義的錯誤信息。
這個標簽檢查
Request
對象的屬性集合來查找一個
reserved key
。如果它找到一個
reserved key
,它就假設這個
key
是一個
String
、或是一個
String
數組(它包含在模塊的
MessageResources
中查找的
message keys
)、或是類型為
org.apache.struts.action.ActionErrors
的一個對象。
如果在應用程序資源中存在相應的信息,那么就可以用下面這些可選的
message keys
:
· errors.header
:相應的信息在錯誤信息的單獨列表前顯示
· errors.footer
:相應的信息在錯誤信息的單獨列表后顯示
· errors.prefix
:相應的信息在錯誤信息的單獨列表前顯示
· errors.suffix
:相應的信息在錯誤信息的單獨列表后顯示
?Struts HTML
標簽庫會使開發更容易、更快速。為了有效地運用這個標簽庫,你需要對標簽庫中的標簽很熟悉。在本系列文章的第一部分中,你學習了如何配置一個
Struts
應用程序來運用標簽庫,并對獨立的標簽有了總體的了解。
在下面第二部分中,你將學習與
form
相關的標簽,講述了如何使用
Struts
提供的
form
相關的標簽。
與
form
相關的標簽包括
<form>
標簽本身以及所有必須包含在其中的標簽。比如,
<text>
和
<password>
標簽就是和
form
相關的標簽,因為如果不把它們放到一個
form
中它們就沒有意義。
<form>
標簽
<form>
標簽用于生成一個
HTML form
。使用該標簽時必須遵循許多規則。
首先要遵循的規則是
,
<form>
標簽中必須包含一個
action
屬性,它是這個標簽中唯一必需的屬性。如果不具備該屬性則
JSP
頁面會拋出一個異常。之后你必須給這個
action
屬性指定一個有效值。一個有效值是指應用程序的
Struts
配置文件中
<action-mappings>
元素里的任何一個
<action>
子元素的訪問路徑。而且相應的
<action>
元素中必須有一個
name
屬性,它的值是
form bean
的名稱。
例如,如果你有這樣一個
<form>
標簽:
?? <html:form action="/login" >
那么你的
Struts
配置文件的
<action-mappings>
元素中必須有一個如下顯示為粗體的
<action>
元素:
<action-mappings>
???? <action path="/login"
????? type="com.javapro.struts.LoginAction"?
????? name="loginForm"
????? scope="request"
????? input="/login.jsp">
????? <forward name="success" path="/mainMenu.jsp"/>
??? </action>
??? .
??? .
??? .
? </action-mappings>
?
這就是說一個
form
標簽是和
form bean
相關聯的。
另一個要遵循的規則是:
任何包含在
<form>
中用來接收用戶輸入的標簽(
<text>
、
<password>
、
<hidden>
、
<textarea>
、
<radio>
、
<checkbox>
、
<select>
)必須在相關的
form bean
中有一個指定的屬性值。比如,如果你有一個屬性值被指定為
“username”
的
<text>
標簽,那么相關的
form bean
中也必須有一個名為
“username”
的屬性。輸入
<text>
標簽中的值會被用于生成
form bean
的
userName
屬性。
除了上面所講的屬性之外,
<form>
標簽還有一些不是必須但加上更好的
“
次要
”
的屬性
。比如,你可以用
focus
屬性來生成
JavaScript
,它會
“
定焦
”
(
focus
)到該
form
所包含的一個元素上。使用
focus
屬性時你需要給它指定元素的名稱。比如,以下代碼是定焦在第二個
Text
元素上的:
<body>
<html:form action="/login" focus="password">
User Name: <html:text property="userName"/>
<br>Password: <html:text property="password"/>
<br><html:submit/>
</html:form>
</body>
該段代碼會被轉換成:
<body>
<form name="loginForm" method="post" action="/myStrutsApp6/login.do">
User Name: <input type="text" name="userName"? value="">
<br>Password: <input type="text" name="password" value="">
<br><input type="submit" value="Submit">
</form>
<script language="JavaScript"
?? type="text/javascript">
? <!--
?if (document.forms["loginForm"].elements["password"].type != "hidden")
??? document.forms["loginForm"].elements["password"].focus()
? // -->
</script>
</body>
注意,
<form>
標簽中
method
屬性的缺省值是
POST
。另外,有沒有看到這個標簽庫是如何建立
JavaScript
來定焦到
password
元素上的
?
這也是該庫讓人著迷的地方之一。你不用擔心如何在客戶端進行編程,它會幫你自動生成。
在運行前面的例子時還要注意,你必須有一個包含
userName
和
password
屬性的相關
form
。你可以參考本文第三部分中的
Login
程序。
<text>
標簽
<text>
標簽用于生成一個文本的輸入區域。它必須包含和相關
form bean
中的相同屬性對應的
“property”
屬性。該標簽只有在嵌入到一個
<form>
標簽中時才有效。
例如:
<html:text property="userName"/>
會被轉換成:
<input type="text" name="userName" value="">
<password>
標簽
<password>
標簽用于生成一個口令字(
type password
)的輸入區域。它必須包含和相關
form bean
中的相同屬性對應的
“property”
屬性。該標簽只有在嵌入到一個
<form>
標簽中時才有效。該標簽中的一個很重要的屬性是
“redisplay”
,它用于重新顯示以前輸入到這個區域中的值。該屬性的缺省值為
true
。然而,為了使
password
不能被重新顯示,你或許希望將該屬性的值設為
false
。
例如:
<html:password property="password" redisplay="false"/>
會被轉換成
:
<input type="password" name="password" value="">
<hidden>
標簽
<hidden>
標簽用于生成一個隱藏文本的輸入區域。它必須包含和相關
form bean
中的相同屬性對應的
“property”
屬性。該標簽只有在嵌入到一個
<form>
標簽中時才有效:
例如:
<html:hidden property="userName"/>
會被轉換成
:
<input type="hidden" name="userName" value="">
<textarea>
標簽
<textarea>
標簽用于生成一個文本區元素(
text area element
)。它必須包含和相關
form bean
中的相同屬性對應的
“property”
屬性。
比如:
<html:textarea property="details" cols="80" rows="20" value="Enter details here"/>
會被轉換成:
<textarea name="details" cols="80" rows="20">Enter details here</textarea>
<radio>
標簽
<radio>
標簽用于顯示一個單選按鈕(
radio button
)。它必須包含
“value”
屬性。比如這段代碼:
<html:radio property="title" value="1"/>Mr.
<html:radio property="title" value="2"/>Ms.
<html:radio property="title" value="3"/>Dr.
會被轉換成這樣的
HTML
:
<input type="radio" name="title" value="1">Mr.
<input type="radio" name="title" value="2">Ms.
<input type="radio" name="title" value="3">Dr.
<checkbox>
標簽
<checkbox>
標簽用于顯示
checkbox
類型的輸入區域。比如:
<html:checkbox property="notify"/>Please send me notification
會被轉換成:
<input type="checkbox" name="notify" value="on">Please send me notification
<submit>
標簽
<submit>
標簽用于生成提交類型(
type submit
)的輸入區域。
比如:
<html:submit value="Login"/>
會被轉換成:
<input type="submit" value="Login">
?
<reset>
標簽
<reset>
標簽用于生成重置類型(
type reset
)的輸入區域。比如:
<html:reset/>
會被轉換成:
<input type="reset" value="Reset">
<option>
標簽
<option>
標簽用于顯示
select box
中的一個選項。參照下面的
<select>
標簽。
<select>
標簽
<select>
標簽用于顯示一個包含零個或更多選項的
HTML
選擇元素。它必須被嵌入一個
<form>
標簽中才有效。下面這個例子將說明如何使用該標簽:
<html:select property="color" size="3">
? <html:option value="r">red</html:option>
? <html:option value="g">green</html:option>
? <html:option value="b">blue</html:option>
</html:select>
會被轉換成:
<select name="color" size="3"><option value="r">red</option>
? <option value="g">green</option>
? <option value="b">blue</option>
</select>
在本文系列的第二部分,你學到了一些更重要的和 form 相關的標簽。在使用這些標簽之前,你必須依照一些規則以便正確地運用它們。第三部分將講述如何在真正的程序中使用這些標簽。
在本文系列的第一部分中,你已經學習了如何配置
Struts
提供的
HTML
標簽庫以及獨立使用的標簽;在第二部分中你學習了和
form
相關的標簽;在第三部分中,你將學習如何在
Login
程序中使用
HTML
標簽庫。你可以點此下載該程序。如果你閱讀過關于
Struts
的系列文章(包含六個部分),你會發現這個
Longin
程序是上次我們討論過的
Login
程序的增強版。
圖
1.
應用程序目錄結構
這個
Login
程序是一個簡單的
Struts
程序,它將顯示如何使用
HTML
標簽庫,尤其是和
form
相關的標簽和用于錯誤處理的標簽。其目錄結構如圖
1
中所示。
本文將介紹程序中每個類之間的關系以及它們所起的作用。注意,你必須自己將所有的庫文件復制到
WEB-INF/lib
目錄下;為了節省下載時間它們沒有被包含在
ZIP
文件中。
視圖
MVC
范例中有三種作為視圖的
JSP
頁面:
login.jsp
、
mainMenu.jsp
和
viewSecret.jsp
。
login.jsp
文件中包含一個用于用戶登錄的
form
,
mainMenu.jsp
中顯示了兩個鏈接(注銷(
log out
)和查看公司機密),而
viewSecret.jsp
則用來顯示一條機密消息。
這個程序的首頁面是一個
Login
頁面,它是一個包含兩個輸入框(
userName
和
password
)的
form
(見圖
2
)。用戶被要求在這兩個輸入框中輸入正確的值。登錄成功之后程序會顯示
mainMenu.jsp
頁面,它包含兩個鏈接:一個是注銷,另一個是查看公司機密賬號(見圖
3
)。
如果點擊了
“
注銷
”
鏈接,程序便會退出并重新顯示
Login
頁面。如果點擊了
“
查看機密
”
鏈接,則會顯示
viewSecret.jsp
頁面。如果注冊失敗,那么用戶會被重新引導到
Login
頁面以重新登錄。
如果點擊了
“
注銷
”
鏈接,程序便會退出并重新顯示
Login
頁面。如果點擊了
“
查看機密
”
鏈接,則會顯示
viewSecret.jsp
頁面。如果注冊失敗,那么用戶會被重新引導到
Login
頁面以重新登錄。
圖
2. Login
頁面
如果用戶輸入正確的用戶名和密碼,程序會建立一個
session
對象,并會有一個名為
loggedIn
的屬性被添加到這個
session
對象中去。只有當程序能夠在用戶的
session
對象中查找到這個
loggedIn
屬性時,用戶才可以瀏覽
Main Menu
頁面和
Secret
頁面。所有缺少該屬性或無效的
session
對象都會迫使用戶登錄。在這個程序中,正確的用戶名是
“john”
,密碼是
“
當用戶注銷時,他或她的
session
對象將失效,同時
Longin
頁面會重新顯示。當用戶點擊鏈接要查看公司機密時,會彈出
viewSecret.jsp
頁面(見圖
4
)。
圖
3.
主頁面
配置文件
Login
程序有兩個位于
WEB-INF
目錄下的配置文件:作為部署描述符的
web.xml
文件(見列表
1
);以及作為
Struts
配置文件的
truts-config.xml
文件
(見列表
2
)。在列表
1
中,你需要特別注意
action servlet
配置中的
<init-param>
元素:
<init-param>
<param-name>application</param-name>
<param-value>com.javapro.struts.ApplicationResources
</param-value>
</init-param>
一個
<init-param>
元素代表一個初始化參數,它會被包含在傳送到
action servlet
中的
ServletConfig
對象里。帶有名為
“application”
的初始化參數對
action servlet
來說具有特殊的意義:它定義了一個會被加載到缺省消息資源(
message resource
)中的屬性文件。(我將在
“
消息資源
”
部分介紹這個屬性文件)。在這個程序中,該屬性文件被用于存貯整個程序中的錯誤消息。
部署描述符中需要注意的第二個地方是的
<taglib>
元素,它包含
<taglib-uri>
和
<taglib-location>
元素。基本上,
<taglib>
元素是用來告訴
servlet
容器如何使用一個標簽庫的,該標簽庫的
TLD
文件可以在
<taglib-location>
元素指定的位置找到。
圖
4.
機密頁面
注意在列表
2
中,
<form-beans>
部分包含一個名為
loginForm
的
form bean
。我在關于
Struts
系列文章的第五部分中曾介紹過
form bean
。
WEB-INF
目錄中的最后一個文件是
struts-html.tld
文件,它是
HTML
標簽庫中的
TLD
文件。為了節省時間我將跳過對它的介紹,但你可以在
ZIP
文件中的
WEB-INF
目錄下找到它。
Form
該
form
以
com.javapro.struts.LoginForm
類的形式顯示(見列表
3
)。注意粗體的部分:它通過傳入
“error.missing.userName”
和
“error.missing.password”
字符串來舉例說明
ActionError
對象,這些字符串在消息資源中起關鍵字(
key
)的作用。
Action
類
Action
類分兩種:
LoginAction
(見列表
4
)和
LogoutAction
(見列表
5
)。另外值得一提的是如何通過消息資源中的一個關鍵字來構建這個
ActionError
消息(在列表
4
中顯示為粗體)。
HTML
標簽庫的使用
列表
6
、列表
7
和列表
8
中分別包含了
JSP
文件。
login.jsp
頁面(見列表
6
)中顯示了如何在
HTML
庫中使用這些標簽(粗體部分)。我在本文系列的第一部分中介紹過這些標簽,但通過看它如何在真正的程序中運行,你會對它們有更深入的了解。
消息資源
如我在
“
配置文件
”
部分簡要介紹的那樣,在
WEB-INF/classes/com/javapro/struts
目錄下的
ApplicationResources.properties
文件中包含配對的
key/values
,它們會被加載到缺省的消息資源中去。
HTML
標簽庫中的
<errors>
標簽會在該消息資源中查找到自定義的錯誤消息。想知道它是如何出錯的,你可以試著用一個錯誤的用戶名或密碼來登錄,看看顯示的錯誤消息是什么。更改錯誤消息和編輯屬性文件一樣容易。看看如下的屬性文件:
errors.header=<b>Error(s)!!!</b><ul>
errors.footer=</ul><hr>
error.missing.userName=<li>A user name was not found.</li>
error.missing.password=<li>A password was not found.</li>
error.login.failed=<li>Incorrect user name and/or password.</li>
如果你檢查了程序的
web.xml
文件,你會看到這些對象是如何被加載的。消息資源通過將程序的參數傳入
ActionServlet
來完成加載過程。在
ActionServlet
進行初始化時,它會將
package
文件夾中的
ApplicationResources.properties
屬性解析為缺省的消息資源。如果在資源中更改一個消息并重新加載程序,它就會在整個程序中顯示。在你的
Login
程序中,這個屬性文件包含一些程序的類中所使用的錯誤消息。
本文介紹了如何在一個簡單的
Login
程序中使用
HTML
標簽庫。它對程序進行了詳細描述,包括視圖、配置文件、
form bean
、
action
類以及用于
JSP
頁面的代碼。