Struts 2常见应用
學習內容
?Struts 2國際化
?Struts 2的異常處理
?Struts 2的文件上傳與下載
能力目標
?熟練使用Struts 2實現國際化
?能通過Struts 2的異常處理增強WEB應用的健壯性
?使用Struts2實現文件上傳與下載
?
?
本章簡介
本章主要介紹Struts 2的常見應用,主要包括Struts 2國際化、Struts 2異常處理和文件上傳與下載。Internet把全世界聯系在了一起,WEB應用可以通過瀏覽器被全世界的人們所使用,所以開發人員需要考慮WEB應用系統在不同地區和語言環境中的使用情況,使WEB
應用系統能在不同的地區和語言環境中以當地的語言進行顯示,這個過程就稱之為國際化。
任何成熟的MVC類框架都應該提供成熟完善的異常處理機制,Struts 2采用了一種聲明式的異常處理機制,從而避免了在程序中編寫大量的try-catch塊,使異常處理和業務代碼不再耦合。
文件的上傳與下載也是WEB應用常見的功能,例如上傳圖片,本章最后會學習使用Struts 2實現文件的上傳與下載。
核心技能部分
9.1?sStruts 2國際化
國際化主要是指語言的國際化,目的是使應用程序能提供一個語言自適應、顯示更友好的用戶界面,掃除語言障礙,使不同地區和使用不同語言的用戶都能方便的使用我們開發的WEB應用系統。Struts 2國際化建立在Java國際化的基礎上,只是對Java國際化進行了進一步的優化和封裝,從而簡化了國際化的實現過程。
9.1.1?Struts 2國際化機制
Struts 2實現國際化的過程需要三個步驟:
(1)?創建中英文資源文件。
(2)?在struts.xml文件中配置資源文件。
(3)?在JSP頁面中使用<s:text />標簽或OGNL顯示國際化信息。
示例9.1
下面我們以添加學生為例來演示Struts 2實現國際化的詳細過程。
(1)?在工程的src根目錄下創建兩個國際化資源文件,分別是英文的資源文件:ApplicationResources_en.properties和中文的資源文件:ApplicationResources_zh.properties,參考代碼如下所示。
文件名:ApplicationResources_en.properties
addstu.title=\u6DFB\u52A0\u5B66\u751F
addstu.name=\u5B66\u751F\u59D3\u540D
addstu.birthday=\u5B66\u751F\u751F\u65E5
addstu.height=\u5B66\u751F\u8EAB\u9AD8
addstu.weight=\u5B66\u751F\u4F53\u91CD
addstu.btn=\u6DFB\u52A0
addstu.exception=\u4E0D\u597D\u610F\u601D\uFF0C\u7A0B\u5E8F\u6682\u65F6\u 51FA\u73B0\u5F02\u5E38\u3002
addstu.en=\u82F1\u6587
addstu.zh=\u4E2D\u6587
文件名:ApplicationResources_zh.properties
addstu.title=add a new Student
addstu.name=student'name
addstu.birthday=student'birthday
addstu.height=student'height
addstu.weight=student'weight
addstu.btn=Add
addstu.exception=Sorry,Program temporarily appear unusual.
addstu.zh=Chinese
addstu.en=EngLish
和Struts 1一樣,國際化資源文件是以properties為擴展名的文本文件,該文本文件以key=value的形式存儲了國際化消息資源。國際化資源文件的命名規則是resourceName_language.properties。其中,resourceName是自定義的資源文件基本名,language是不能自定義的,Java中規定了不同的字符代表不同的國家和地區的語言,zh表示簡體中文,en表示英語。
中文的資源文件因為包含了非西歐字符,所以必須把這個文件通過native2ascii命令進行轉碼,轉碼之后的中文資源文件才能使用,語法如下所示:
語法
native2ascii -encoding UTF-8 原中文資源文件名轉碼后的資源文件名
高版本的MyEclipse會自動對中文資源文件轉碼,因此可以直接編輯。
(2)?在struts.xml文件中配置資源文件,參考代碼如下所示。
<struts>
<constant name="struts.custom.i18n.resources" value="ApplicationResources" />
<package name="student" extends="struts-default">
<action name="add" class="com.zy.StudentAction"></action>
<action name="changeLang" class="com.zy.LanguageAction">
<result name="success">/addStu.jsp</result>
</action>
</package>
</struts>
在struts.xml文件中通過<constant>元素把國際化資源文件的名字告知Struts 2框架,其中name屬性的值必須是"struts.custom.i18n.resources",value屬性的值就是項目中國際化資源文件的名字,注意只寫基本名即可。
(3)?在JSP頁面中顯示國際化信息,參考代碼如下所示。
<%@ page language="java" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title><s:text name="addstu.title"/></title>
</head>
<body>
<center>
<a href="changeLang.action?request_locale=zh_CN">
<s:text name="addstu.zh"/></a>?
<a href="changeLang.action?request_locale=en">
<s:text name="addstu.en"/></a>
</center>
<s:form action="add.action" method="post">
<table>
<tr><td><s:text name="addstu.name"/></td>
<td><s:textfield name="name" /></td></tr>
<tr><td><s:text name="addstu.birthday"/></td>
<td><s:textfield name="birthday" /></td></tr>
<tr><td><s:text name="addstu.height"/></td>
<td><s:textfield name="height" /></td></tr>
<tr><td><s:text name="addstu.weight"/></td>
<td><s:textfield name="weight" /></td></tr>
<tr><td colspan="2">
<s:submit value="%{getText('addstu.btn')}"/>
</td></tr>
</table>
</s:form>
</body>
</html>
在JSP頁面中顯示國際化信息的方式有兩種:
??如果是頁面上單獨的文本,可以使用<s:text/>標簽讀取國際化信息,name屬性的值是資
源文件中的key。
??如果是標簽中的某個屬性值,例如上述代碼中的提交按鈕,這時可以使用%{getText(' key ')}讀取國際化信息,其中key指的就是資源文件中的key。
運行該JSP頁面,效果如圖9.1.1和9.1.2所示。
?
圖9.1.1 中文界面
?
圖9.1.2 英文界面
問了方便用戶自由選擇語言,我們在頁面上放置了兩個超鏈接,單擊【英文】超鏈接后就顯示英文界面,單擊【Chinese】超鏈接后就顯示中文界面,這兩個超鏈接的代碼如下所示。
<a href="changeLang.action?request_locale=zh_CN">
<s:text name="addstu.zh"/></a>
<a href="changeLang.action?request_locale=en">
<s:text name="addstu.en"/></a>
在上述代碼中,超鏈接請求了changeLang.action并傳遞了參數“request_locale”,那么changeLang.action對應的Action類是如何實現中英文界面切換的呢?我們看下面該Action類的代碼。
public class LanguageAction extends ActionSupport {
public String execute()
{
return SUCCESS;
}
}
我們發現該Action類沒有做任何處理,為什么能夠實現中英文界面切換呢?事實上,這個功能是由Struts 2內置的名字是“i18n”的攔截器實現的,該攔截器被添加到了默認的攔截器棧中(defaultStack),具體實現過程如下:
??當客戶端請求發送到服務器端后,Struts 2的i18n攔截器會對客戶端請求進行攔截并獲得參數request_locale的值(zh或cn),該值存儲了客戶端瀏覽器的地區語言環境,獲得該值后i18n攔截器將它實例化成一個Locale對象并存儲在用戶session中一個名字為WW_TRANS_I18N_LOCALE的屬性中,該屬性的值將會作為瀏覽器默認的Locale。
??在獲得了客戶端地區語言環境后,Struts 2會查找struts.xml配置文件來加載國際化資源文件。
??加載好國際化資源文件后,Struts 2的視圖文件會通過Struts 2標簽把國際化消息顯示出來。
9.1.2?校驗配置文件的國際化
上一章我們學習了使用Struts 2內置校驗器進行輸入校驗,這時需要提供一個校驗配置文件,例如下面是登錄案例的校驗配置文件。
<validators>
<field name="name">
<field-validator type="requiredstring">
<message>登錄不能為空!</message>
</field-validator>
</field>
<field name="pwd">
<field-validator type="requiredstring">
<message>登錄密碼不能為空!</message>
</field-validator>
<field-validator type="stringlength">
<param name="minLength">6</param>
<message>密碼長度必須大于等于${minLength}</message>
</field-validator>
</field>
</validators>
在校驗配置文件中可以通過<message>元素設置提示信息,但是如果現在需要對這些提示信息進行國際化處理該怎么辦呢?
示例9.2
假如現在我們要添加學生,要求學生姓名非空,學生身高必須在120cm和220cm之間,考慮到國際化,校驗配置文件可以這樣寫:
<validators>
<field name="name">
<field-validator type="requiredstring">
<message key="addStu.validate.name"/>
</field-validator>
</field>
<field name="height">
<field-validator type="int">
<param name="min">120</param>
<param name="max">220</param>
<message ?key="addStu.validate.height"/>
</field-validator>
</field>
</validators>
<message>元素不再直接設置提示信息了,而是通過key屬性從國際化資源文件中取出信息,key屬性的值就是國際化資源文件中的key。下面是本示例中的資源文件:
中文資源文件:
addstu.title=\u6DFB\u52A0\u5B66\u751F
addstu.name=\u5B66\u751F\u59D3\u540D
addstu.birthday=\u5B66\u751F\u751F\u65E5
addstu.height=\u5B66\u751F\u8EAB\u9AD8
addstu.weight=\u5B66\u751F\u4F53\u91CD
addstu.btn=\u6DFB\u52A0
addstu.exception=\u4E0D\u597D51FA\u73B0\u5F02\u5E38\u3002
addstu.en=\u82F1\u6587
addstu.zh=\u4E2D\u6587
addstu.validate.name=\u5B66\u759D3\u540D\u5FC5\u987B\u586B\u5199\uFF01
addStu.validate.height=\u5B66\u751F\u8E5\u987B\u5728${min}\u548C${max}
英文資源文件:
addstu.title=add a new Student
addstu.name=student'name
addstu.birthday=student'birthday
addstu.height=student'height
addstu.weight=student'weight
addstu.btn=Add
addstu.exception=Sorry,Program temporarily appear unusual.
addstu.zh=Chinese
addstu.en=EngLish
addstu.validate.name=student name is required
addStu.validate.height=student height is must between ${min} and ${max}
其他文件的代碼不變,運行效果如圖9.1.3和圖9.1.4所示。
?
圖9.1.3 中文提示信息
?
圖9.1.4 英文提示信息
9.2?Struts 2異常處理
異常是程序運行時不可避免的情況,所以我們在進行程序開發時必須對異常進行處理。傳統的異常處理方式就是使用try-catch語句,這種處理機制采用的是硬編碼的方式,需要編寫很多重復的代碼,并且不利于維護。而Struts 2作為成熟的MVC框架提供了完善的異常處理機制,采用的是聲明式的異常處理方式,這種方式便于管理和維護。
9.2.1?Struts 2異常處理機制
客戶端發送一個請求后,Struts 2框架會把這個請求交給Action進行處理,在Action進行業務處理的過程中,如果出現異常了,Struts 2中名字為exception的攔截器就會自動攔截該異常并進行處理,然后再轉到相應的視圖頁面反饋給用戶。由于Struts 2把異常交給了exception攔截器進行處理,所以我們無須在Action中編寫try-catch語句塊,只需要在struts.xml中對Action進行異常配置就行了。
struts.xml文件通過使用<exception-mapping />元素來進行異常映射配置,在使用該元素時需要指定兩個屬性:
??exception屬性:該屬性用來指定異常的類型。
??result屬性:該屬性值是一個url地址,用來指定出現異常時Struts 2跳轉到哪個視圖。
根據異常映射起作用的范圍可以把異常映射配置分為全局異常映射和局部異常映射。
??全局異常映射:這種映射使用<global-exception-mapping />元素進行配置,在該元素中嵌套<exception-mapping />作為子元素,這種映射的作用范圍是package中的所有Action。
??局部異常映射:這種映射直接在Action內部使用<exception-mapping />元素配置就行了,當然它的作用范圍為它所在的Action。
這兩種異常映射的優先級不同,如果對一個Action既配置了全局映射又配置了局部映射,那么Struts 2會采用“就進原則”,即使用局部映射進行異常處理。
9.2.2?異常處理示例
示例9.3
下面通過一個示例來具體介紹Struts 2如何進行異常處理。在程序中如果出現除數為0的情況就會出現java.lang.ArithmeticException異常,這個大家都非常熟悉了。本示例就模擬除數為0的情況,如圖9.1.5所示。
?
圖9.1.5 運行效果
JSP頁面的參考代碼如下所示。
<body>
<h3><center>除法計算</center></h3>
<center>
<s:form action="jisuan.action" method="post" theme="simple">
<s:textfield name="a" cssStyle="width:60"></s:textfield>
除以
<s:textfield name="b" cssStyle="width:60"></s:textfield>
等于
<s:textfield name="c" cssStyle="width:60"></s:textfield>
<s:submit value="計算"/>
</s:form></center>
</body>
Action的代碼如下所示。
public class jisuanAction ?extends ActionSupport{
private int a; ???//被除數
private int b; ??//除數
private int c; ??//結果
//省略getter和setter方法
public String jisuan()
{
this.c=this.a/this.b;
return SUCCESS;
}
}
異常提示頁面error.jsp的代碼如下所示。
<body>
<center><h2>出現除0異常</h2></center>
</body>
重點是下面的配置文件,代碼如下所示。
<package name="struts2_math" extends="struts-default">
<global-results>
<result name="error">/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="error"
?exception="java.lang.ArithmeticException">
</exception-mapping>
</global-exception-mappings>
<action name="jisuan" class="com.zy.jisuanAction" method="jisuan">
</action>
</package>
我們在配置文件的<global-exception-mappings>元素中配置了一個異常映射用來處理除0異常,如果有除0異常發生就跳轉到error.jsp頁面,如圖9.1.6所示。
?
圖9.1.6 異常提示
9.3?Struts 2文件上傳
文件上傳是WEB應用中經常遇到的問題,Struts 2默認使用Jakarta的Common-FileUpload文件上傳框架,并對其進行了優化和封裝。在實際應用中,需要把commons-io-xxx.jar和commons-fileupload-xxx.jar(xxx是版本號)導入到WEB項目中。我們通過MyEclipse 添加Struts支持時會默認導入這兩個Jar文件,如圖9.1.7所示。
?
圖9.1.7 導入Jar
9.3.1?單文件上傳
示例9.4
文件上傳中最簡單的是上傳一個文件,下面我們通過一個示例介紹如何使用Struts 2實現單文件上傳。
(1)?創建表單提供上傳文件的操作入口,代碼如下所示。
<body>
<s:form action="up.action" method="post" enctype="multipart/form-data">
<s:file name="upload" label="請選擇上傳文件"/>
<s:submit value="上傳"/>
</s:form>
</body>
需要注意:<s:form>標簽必須指定enctype屬性并且該屬性的值必須是“multipart/form-data”,這表示表單的數據不再以字符串的形式提交,而是以二進制編碼的形式來提交數據。
(2)?創建實現在服務器端接收上傳文件并保存到指定位置功能的Action,代碼如下所示。
public class MyUpAction extends ActionSupport{
??private File upload; ??//對應表單中文件域的名字
??private String uploadContentType; ???//文件類型
??private String uploadFileName; ??????//文件名字
//省略getter和setter方法
??public String execute() throws Exception
??{
//獲取服務器上保存文件的路徑和上傳文件的名字,本示例的路徑是/upfile
??????String fileName=ServletActionContext.getServletContext().
getRealPath("/upfile")+"\\"+getUploadFileName();
//文件輸出流
??????FileOutputStream fos=new FileOutputStream(fileName);
//文件上傳流
??????FileInputStream fis=new FileInputStream(getUpload()); ?
//下面的代碼把上傳到服務器的文件保存(寫入)到指定文件夾中
??????byte[] b=new byte[1024];
??????int len=0;
//通過循環把文件二進制數據寫入到服務器
??????while((len=fis.read(b))>0)
??????{
????????fos.write(b,0,len);
??????}
??????return this.SUCCESS;
??}
}
該Action與普通Action的差別不大,upload屬性封裝了表單中的文件域;uploadContentType封裝上傳文件的類型;uploadFileName封裝上傳文件的名字。以上三個屬性是必須的并且Struts 2會從文件域中解析出來自動賦值給Action。一般情況下,如果表單中包含一個name屬性為xxx的文件域,那么就需要在Action中使用如下的三個屬性來封裝文件域信息:
private File xxx:封裝文件域對應的文件內容。
?private String xxxFileName:封裝上傳文件的文件名。
?private String xxxContentType:封裝上傳文件的文件類型。
通過封裝上述三個屬性之后就可以在execute方法中實現文件上傳功能了。在execute方法中主要通過文件輸入輸出流實現文件的上傳。
(3)?上傳成功后跳轉到另外一個頁面顯示文件的名字,如果是圖片就把圖片顯示到頁面上,參考代碼如下所示。
<body>
<h3>文件上傳成功</h3>
<s:property value="uploadFileName"/><br>
<img src="upfile/<s:property value="uploadFileName"/>"/>
</body>
(4)?在struts.xml文件中進行配置,參考代碼如下所示。
<package name="upfile" extends="struts-default">
<action name="up" class="com.zy.MyUpAction">
<interceptor-ref name="fileUpload">
<param name="allowedExtensions">.bmp,.gif,.jpg</param>
<param name="maximumSize">1000000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
<result name="success" type="dispatcher">/up_success.jsp</result>
<result name="input" >/up_success.jsp</result>
</action>
</package>
為了對上傳文件的類型和大小進行限制,我們為Action配置了名字是“fileUpload”的攔截器,該攔截器由Struts 2框架提供,專門用來限制上傳文件的類型和大小。在使用的時候需要指定兩個參數:
??allowedExtensions:該參數用來限制文件類型,需要給出擴展名,多個擴展名之間用逗
號隔開。
??maximumSize:該參數用來限制文件大小,單位是字節。
如果上傳文件失敗了,Struts 2會自動轉入到input結果視圖,所以必須為Action配置input結果視圖。另外,我們必須配置defaultStack默認攔截器棧,并且必須放在fileUpload攔截器的后面。
Struts 2默認情況下最大只能上傳2M的文件,超過2M的話maximumSize參數也不起作用,會直接出現異常。為了解決這個問題,我們可以在struts.xml文件中配置struts.multipart.maxSize常量,參考代碼如下所示。
<constant name="struts.multipart.maxSize" value="1000000000"/>
我們上傳一張圖片,運行效果如圖9.1.8和10.1.9所示。
?
圖9.1.8 上傳圖片
?
圖9.1.9 上傳成功
?
9.3.2?多文件上傳
示例9.5
在WEB應用中,一次上傳多個文件也是很常見的情況,這時我們只需在上述實現單文件上傳的代碼的基礎上稍作修改即可,與單文件上傳的本質是一樣的。
(1)?修改表單,增加幾個文件域,參考代碼如下所示。
<body>
<s:form action="up_m.action" method="post" enctype="multipart/form-data">
請選擇您要上傳的文件:<br>
<s:file name="upload" label="圖片1"/>
<s:file name="upload" label="圖片2"/>
<s:file name="upload" label="圖片3"/>
<s:submit value="上傳" />
</s:form>
</body>
多個文件域的name屬性值保持一致。
(2)?修改實現上傳的Action,參考代碼如下所示。
public class MyUpAction_m extends ActionSupport {
//由于是多文件上傳,所以下面三個屬性都改成了數組
??private File[] upload;
??private String[] uploadContentType;
??private String[] uploadFileName;
//省略getter和setter方法
??public String execute() throws Exception
??{
??????File[] files=getUpload();
//由于是多文件上傳,所以在源代碼的基礎上增加了for循環
??????for(int i=0;i<files.length;i++)
??????{
????????String fileName=ServletActionContext.getServletContext().
getRealPath("/upfile")+"\\"+getUploadFileName()[i];
????????FileOutputStream fos=new FileOutputStream(fileName);
????????FileInputStream fis=new FileInputStream(files[i]); ?????
????????byte[] b=new byte[1024];
????????int len=0;
????????while((len=fis.read(b))>0)
????????{
??????????fos.write(b,0,len);
????????}
??????}
??????return this.SUCCESS;
??}
}
(3)?修改上傳成功后的頁面,參考代碼如下所示。
<s:iterator value="uploadFileName" id="name">
<s:property value="name"/>
<img src="upfile/<s:property value="name"/>"/>
</s:iterator>
由于要顯示多個文件,所以這里使用了<s:iterator>迭代器來進行循環顯示。
struts.xml無需修改,運行效果如圖9.1.10和圖9.1.11所示。
?
圖9.1.10 多文件上傳
?
圖9.1.11上傳成功
本章總結
??國際化主要是指語言的國際化,目的是使應用程序能提供一個語言自適應、顯示更友好的用戶界面,掃除語言障礙,使不同地區和使用不同語言的用戶都能方便的使用我們開發的WEB應用系統。
(1)創建中英文資源文件。
(2)在struts.xml文件中配置資源文件。
(3)在JSP頁面中使用<s:text />標簽或OGNL顯示國際化信息。
??Struts 2作為成熟的MVC框架提供了完善的異常處理機制,采用的是聲明式的異常處理方式,這種方式便于管理和維護,struts.xml文件通過使用<exception-mapping />元素來進行異常映射配置。
(1)exception屬性:該屬性用來指定異常的類型。
(2)result屬性:該屬性值是一個url地址,用來指定出現異常時Struts 2跳轉到哪個視圖。
(3)全局異常映射:這種映射使用<global-exception-mapping />元素進行配置,在該元素中嵌套<exception-mapping />作為子元素,這種映射的作用范圍是package中的所有Action。
(4)局部異常映射:這種映射直接在Action內部使用<exception-mapping />元素配置就行了,當然它的作用范圍為它所在的Action。
??文件上傳是WEB應用中經常遇到的問題,Struts 2默認使用Jakarta的Common-FileUpload文件上傳框架,并對其進行了優化和封裝。
(1)<s:form>標簽必須指定enctype屬性并且該屬性的值必須是“multipart/form-data”,這表示表單的數據不再以字符串的形式提交,而是以二進制編碼的形式來提交數據。
(2)實現在服務器端接收上傳文件并保存到指定位置功能的Action。
(3)fileUpload攔截器,該攔截器由Struts 2框架提供,專門用來限制上傳文件的類型和大小。
任務實訓部分
1:添加管理員功能國際化
訓練技能點
??國際化
??<s:text>和OGNL顯示國際化消息
需求說明
在上一章的任務實訓部分我們實現了對添加管理員的輸入驗證,現在要求對該案例進行國際化處理,支持中文、英文的切換。
實現步驟
(1)?創建中英文國際化資源文件,參考代碼如下所示
英文資源文件:
addadmin.title=add a new Administrator
addadmin.name=name
addadmin.pwd=password
addadmin.submit=submit
addadmin.validate.name.null=name is required!
addadmin.validate.pwd.null=password is required!
addadmin.validate.pwd.length=password'length must be more than 6
addadmin.validate.pwd2=Two of the input password must be equal
addadmin.lang=ChooseLanguage
addadmin.zh=Chinese
addadmin.en=EngLish
中文資源文件:
addadmin.title=\u6DFB\u52A0\u7BA1\u7406\u5458
addadmin.name=\u767B\u5F55\u540D\u79F0
addadmin.pwd=\u767B\u5F55\u5BC6\u7801
addadmin.submit=\u63D0\u4EA4
addadmin.validate.name.null=\u767B\u5F55\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A\uFF01
addadmin.validate.pwd.null=\u767B\u5F55\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A\uFF01
addadmin.validate.pwd.length=\u5BC6\u7801\u957F\u5EA6\u5FC5\u987B\u5927\u4E8E6\uFF01
addadmin.validate.pwd2=\u4E24\u6B21\u8F93\u5165\u7684\u5BC6\u7801\u5FC5\u987B\u4E00\u81F4\uFF01
addadmin.lang=\u8BED\u8A00\u9009\u62E9
addadmin.zh=\u4E2D\u6587
addadmin.en=\u82F1\u6587
(2)?下面是實現輸入驗證的Action,參考代碼如下所示。
public class AddAction extends ActionSupport {
private String logName;
private String logPwd1;
private String logPwd2;
public String execute() {
AdminDao ad=new AdminDao();
if(ad.addAdmin(logName, logPwd1))
return SUCCESS;
else
return ERROR;
}
public void validate()
{
if(logName==null||logName.equals(""))
this.addFieldError("logName",
getText("addadmin.validate.name.null"));
if(logPwd1==null||logPwd1.equals(""))
this.addFieldError("logPwd1",
getText("addadmin.validate.pwd.null"));
if(logPwd1.length()<6||logPwd2.length()>10)
this.addFieldError("logPwd1", )
getText("addadmin.validate.pwd.length"));
if(!logPwd1.equals(logPwd2))
this.addFieldError("logPwd2", getText("addadmin.validate.pwd2"));
}
//省略getter和setter方法
}
在通過addFieldError方法添加提示信息時,請注意這里使用了getText。
(3)?下面是添加管理員的表單,代碼如下所示。
<body>
<h3><s:text name="addadmin.title"/></h3>
<s:text name="addadmin.lang"/>:<select οnchange="changeLocal(this.value)" id="lang">
<option value="zh"><s:text name="addadmin.zh"/></option>
<option value="en"><s:text name="addadmin.en"/></option>
</select>
<s:form action="add.action" method="post">
<s:textfield name="logName" label="%{getText('addadmin.name')}"/>
<s:password name="logPwd1" label="%{getText('addadmin.pwd')}"/>
<s:password name="logPwd2" label="%{getText('addadmin.pwd')}"/>
<s:submit value="%{getText('addadmin.submit')}"/>
</s:form>
</body>
<script>
??if(location.search=="")
location="changeLang.action?request_locale=zh";
??else if(location.search=="?request_locale=zh")
document.getElementById("lang").selectedIndex=0;
??else
document.getElementById("lang").selectedIndex=1;
function changeLocal(val)
{
location="changeLang.action?request_locale="+val;
}
</script>
這里我們要求用戶可以自由選擇語言環境,但不是通過超鏈接實現的,而是通過下拉列表框,如圖9.2.1所示,所以必須通過JavaScript代碼進行控制。
?
圖9.2.1 中文界面
?
圖9.2.2 英文界面
2:國際化校驗配置文件
訓練技能點
??Struts 2內置校驗器
??國際化校驗配置文件
需求說明
上個實訓任務是通過重寫ActionSupport類的valudate方法來實現輸入校驗的,現在要求使用Struts 2的內置校驗器實現輸入校驗并實現校驗配置文件的國際化。
3:數據庫操作異常處理
訓練技能點
??Struts 2異常處理
需求說明
在使用JDBC進行數據庫操作時很容易出現異常,所以通常我們都需要對進行數據庫操作的代碼使用try-catch語句,但是這也不能滿足復雜項目的需求,現在要求為添加管理員的示例使用Struts 2完善異常處理,為Action配置全局異常映射。
4:添加學生照片
訓練技能點
??Struts 2文件上傳
需求說明
前面我們實現過一個添加學生的示例,現在要求在添加學生信息的時候必須保存學生的照片,請使用Struts 2文件上傳實現該功能。
實現步驟
(1)?在表單中增加文件域,代碼如下所示:
<body>
<s:form action="addStu.action" method="post"
?enctype="multipart/form-data">
<s:textfield name="name" label="學生姓名"/>
<s:textfield name="birthday" label="學生生日"/>
<s:textfield name="height" label="學生身高"/>
<s:textfield name="weight" label="學生體重"/>
<s:file name="upload" label="學生照片"/>
<s:submit value="添加"/>
</s:form>
</body>
注意為表單增加enctype="multipart/form-data"。
(2)創建實現上傳的Action,參考代碼如下所示:
public class MyUpAction extends ActionSupport{
private String name; ??//學生姓名
private String birthday; ??//學生生日
private int height; ???????//學生身高
private int weight; ??????//學生體重
?//封裝上傳文件域的屬性
private File upload;
//封裝上傳文件的類型
private String uploadContentType;
//封裝上傳文件名
private String uploadFileName;
//方法省略
}
(3)上傳成功后,把學生的相關信息顯示到頁面上,運行效果如圖9.2.3和圖9.2.4所示。
?
圖9.2.3 添加學生
?
圖9.2.4 顯示學生信息
?
鞏固練習
一、選擇題
1. 用來讀取國際化資源文件的Struts 2標簽是()。
A.?<s:textfield>
B.?<s:text>
C.?<s:message>
D.?<s:resource>
2.以下關于Struts 2的國際化資源文件說法正確的是()。
A.?資源文件的名字可以自定義,沒有任何規定
B.?資源文件只要放在正確的路徑下,Struts就能找到了,無需在struts-config.xml中進行任何配置
C.?資源文件只能放在WEB-INF/classes的根目錄下
D.?中文資源文件需要轉碼
3.以下關于Struts 2異常處理說法正確的是()。
A.?通過Struts 2的異常處理機制可以避免異常的發生
B.?Struts 2的異常處理需要名字為exception的攔截器
C.?全局異常映射的作用范圍是struts.xml中的所有Action
D.?全局異常映射的優先級高于局部異常映射
4.以下關于Struts 2異常處理說法正確的是()。
A.?通過Struts 2的異常處理機制可以避免異常的發生
E.?Struts 2的異常處理需要名字為exception的攔截器
F.?全局異常映射的作用范圍是struts.xml中的所有Action
G.?全局異常映射的優先級高于局部異常映射
5.以下關于Struts 2文件上傳說法錯誤的是()。
A.?表單必須設置enctype屬性
B.?通過名字是“fileUpload”的攔截器可以限制文件類型和大小
C.?Struts 2對上傳文件的大小沒有任何限制
D.?Struts 2支持多文件上傳?
二、上機練習
上一章的鞏固練習部分要求大家實現了一個注冊功能,現在在此基礎上使用Struts 2實現國際化和照片上傳功能。
總結
以上是生活随笔為你收集整理的Struts 2常见应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Struts2 类型转换和数据校验
- 下一篇: java调用天气预报的webservic