天天看點

struts2國際化全例 錯誤解決

在struts2中需要做國際化的有:

jsp頁面的國際化,action錯誤資訊的國際化,轉換錯誤資訊的國際化,校驗錯誤資訊的國際化

在之前的例子中已經做過和國際化相關的例子了,在struts.xml中配置過

<constant name="struts.custom.i18n.resources" value="message"></constant>   

其中的message就是國際化資源檔案的baseNmae。

我們先看看簡單的在jsp中進行國際化

在src目錄下建立message_en_US.properties,内容為

hello=add user

建立message_zh_CN.properties檔案,内容為

hello=\u589e\u52a0\u7528\u6237

然後修改register2.jsp

要想使用國際化顯示,可以将資訊添加到<s:text></s:text> 标簽中,也可以放在<s:i18n></s:i18n> 中,

在這裡,先使用标簽 <s:text></s:text>

增加以下内容:

<s:text name="hello"></s:text>   

重新開機伺服器後,浏覽該頁,預設會顯示出“增加使用者”,可以在IE中打開Internet選項,在正常中選擇語言,增加英語(美國)[en-US],然後設定為第一項,重新整理就可以看到輸出“add user”。

這邊很可能會出一種錯誤,如下:

The Struts dispatcher cannot be found.  This is usually caused by using Struts tags without the associated filter. Struts tags are only usable when

the request has passed through its servlet filter, which initializes the Struts dispatcher needed for this tag. - [unknown location]

 at org.apache.struts2.views.jsp.TagUtils.getStack(TagUtils.java:60)

 at org.apache.struts2.views.jsp.StrutsBodyTagSupport.getStack(StrutsBodyTagSupport.java:44)

 at org.apache.struts2.views.jsp.ComponentTagSupport.doStartTag(ComponentTagSupport.java:48)

 at org.apache.jsp.basicinfo.basicInfo_jsp._jspx_meth_struts_005fform_005f0(basicInfo_jsp.java:122)

 at org.apache.jsp.basicinfo.basicInfo_jsp._jspService(basicInfo_jsp.java:93)

 at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

 at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

 at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:386)

 at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)

 at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)

 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)

 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)

 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)

 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)

 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)

 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)

 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)

 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)

 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)

 at java.lang.Thread.run(Thread.java:619)

web.xml相關配置如下:

  <filter>

   <filter-name>struts2</filter-name>

   <filter-class>

    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

   </filter-class>

 <init-param>

  <param-name>config</param-name>

  <param-value>struts-default.xml,struts-plugin.xml,/config/struts.xml </param-value>

 </init-param>    

  </filter>

  <filter-mapping>

   <url-pattern>*.action</url-pattern>

  </filter-mapping>

原因是因為過濾器隻過濾action結尾的請求

但我在JSP頁面中使用了 struts的tag

是以請求不會被struts的過濾器處理

标簽也就無法解析

修改web.xml即可:

<url-pattern>/*</url-pattern>

action錯誤的國際化

在message_en_US.properties中增加以下内容

username.invalid=username invalid...

在message_zh_CN.properties中增加以下内容

username.invalid=\u7528\u6237\u540d\u4e0d\u5408\u6cd5...

修改RegisterAction中的validate方法,将錯誤加到ActionError中,在這裡将使用到ActionSupport中的getText方法獲得和國際化資源檔案相關的資訊。

以username驗證為例:

if (null == username || username.length() < 5 || username.length() > 10) {   

    this.addActionError(this.getText("username.invalid"));   

}   

這樣就從資源檔案中讀取username.invalid的值,增加到ActionError中。

檢視該頁面不輸入任何資料,送出後就可以看到顯示效果了。

驗證架構的國際化(field級别錯誤)

在message_en_US.properties檔案中增加以下内容

username.xml.invalid=validate information

在message_zh_CN.properties檔案中增加以下内容

username.xml.invalid=\u9a8c\u8bc1\u6846\u67b6\u4fe1\u606f

然後修改驗證架構,需要将在properties檔案中的内容增加到架構中。

以username為例 

<field name="username">   

    <field-validator type="requiredstring">   

        <param name="trim">true</param>   

        <message key="username.xml.invalid"></message>   

    </field-validator>   

</field>   

在message标簽中增加屬性key,值為properties檔案中的key

标簽中key大多是和國際化相關的

國際化資源檔案的分類

當應用程式很大時,需要國際化的東西會很多,是以需要将國際化資源檔案進行分類。

需要知道的是在src中的properties檔案是全局資源檔案,另外還可以分為包級别的和類級别的

首先看看包級别的

命名規則為package_language_country.properties

建立package_en_US.properties,内容為

username.xml.invalid=package validate information

建立package_zh_CN.properties,内容為

username.xml.invalid=\u5305\u9a8c\u8bc1\u4fe1\u606f

可以看到輸出的資訊為“包驗證資訊”,由此可見包級别的國際化資源檔案的優先級高于全局國際化資源檔案。

類級别

建立RegisterAction_en_US.properties,内容為

username.xml.invalid=class validate information

建立RegisterAction_zh_CN.properties,内容為

username.xml.invalid=\u7c7b\u9a8c\u8bc1\u4fe1\u606f

此時可以看到輸出的資訊為“類驗證資訊”。

由此可以得到國際化資源檔案的優先級

全局<包級别<類級别

另外要進行表單的國際化時,要去掉theme="simple"

在RegisterAction_en_US.properties中增加

username.name=username

在RegisterAction_zh_CN.properties中增加

username.name=\u7528\u6237\u540d

修改表單标簽

<s:textfield name="username" key="username.name"></s:textfield>   

注意到key一般是和國際化相關的。

另外除了用

另外除了用<s:text>這個标簽外,還可以使用<s:i18n>這個标簽

<s:i18n name="temp"></s:i18n>   

标簽中包含name,代表着可以定義資源檔案的baseName,如可以定義成temp,那麼對應着

temp_en_US.properties和temp_zh_CN.properties這兩個資源檔案。

如定義:

<s:i18n name="hello">   

    <s:text name="world">   

        <s:param>struts2</s:param>   

    </s:text>   

</s:i18n>   

注意到可以在<s:text>标簽中增加<s:i18n> 标簽。

在hello_en_US.properties檔案中增加

world=hello {0}

hello_zh_CN.properties中增加

world=\u4f60\u597d,struts2

在struts2的預設攔截器棧中已經定義了i18n攔截器,是以struts2已經是一個國際化的架構了。

struts2會查找從用戶端送出的request_locale屬性,并存到session中的WW_TRANS_I18N_LOCALE字段

中。

這個<s:text> 标簽外,還可以使用<s:i18n> 這個标簽  

 總結一下顯示方法: 

<s:textname="hello"></s:text>

getText("username.invalid") 

<message key="username.xml.invalid"></message>  

<s:textfield name="username" key="username.name"></s:textfield>    

<s:i18n name="temp"></s:i18n>