Struts2學習筆記 | 消息處理與國際化

配置國際化資源文件

  • Action範圍資源文件
    在Action類文件所在的路徑建立名爲ActionName_language_country.properties的文件。
    例如:Action類爲Testi18nAction的話,則命名爲Testi18nAction_en_US.properties

  • 包範圍資源文件
    在包的根路徑下建立文件名爲package_language_country.properties的屬性文件,一旦建立,處理該包下的所有Action都可以訪問該資源文件。
    注意:包範圍資源文件中的baseName就是package,不是Action所在的包名

  • 全局資源文件
    命名方式:basename_language_country.properties
    struts.xml中配置:<constant name="struts.custom.i18n.resources" value="baseName">
    例如:命名爲i18n_en_US.properties,在struts.xml中配置:<constant name="struts.custom.i18n.resources" value="i18n">

  • 國際化資源文件加載的順序
    離當前Action較近的將被優先加載


在頁面上和Action類中訪問國際化資源文件

  • 在Action類中,若Action實現了TextProvider接口,則可以調用其getText()方法獲取value
    通過繼承ActionSupport就能間接實現TextProvider接口。

  • 頁面上可以使用<s:text>標籤,對於表單標籤可以使用標籤標籤的key屬性值
    若有佔位符,則可以使用<s:text>標籤的<s:param>子標籤來填充佔位符。
    可以利用標籤和OGNL直接訪問值棧中的屬性值,包括對象棧和Map棧

Demo:
使用全局進行配置:
struts.xml中配置<constant name="struts.custom.i18n.resources" value="i18n"></constant>

jsp代碼:


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <s:form action="">
        <!-- key是直接上資源文件中獲取value值 -->
        <s:textfield name="username" key="username"></s:textfield>
        <!-- 如果不用key屬性,則也可以強制使用OGNL標籤來調getText()方法獲取value值-->
        <s:textfield name="username" label="%{getText('username')}"></s:textfield>
        
        <s:textfield name="password" key="password"></s:textfield>
        <s:submit key="submit"></s:submit>
    </s:form>
</body>
</html>

對於上述的Demo,在<s:textfield name="username" key="username"></s:textfield>有使用到key屬性,因此可以直接獲取國際化資源文件value值,如果不使用key屬性,而是使用label屬性,則可以<s:textfield name="username" label="%{getText('username')}"></s:textfield>獲取,因爲此時在對象棧中有DefaultTextProvi 的一個實例,該對象中提供了訪問國際化資源文件的getText()方法。並且在字符串中要進行強制的OGNL解析,因此需要%{}。但是這只是在主題不是simple的情況下。如果主題是simple的話,上述代碼不能實現,應該使用<s:text>標籤,因此做一些修改如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <s:form action="" theme="simple">

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

        <s:text name="username"/>:<s:textfield name="username" label="%{getText('username')}"></s:textfield>

        <s:text name="password"/>:<s:textfield name="password" key="password"></s:textfield>
        <s:submit key="submit" value="%{getText('submit')}"></s:submit>
    </s:form>
</body>
</html>
  • 訪問帶佔位符的Demo
    需要自己編寫一個繼承ActionSupport的Action類,在值棧中填入帶佔位符的屬性即可。
    在jsp頁面中用到<s:text>標籤並在該標籤中使用<s:param>子標籤填充屬性即可。

Testi18nAction類:

package com.cerr.struts2.i18n.app;

import com.opensymphony.xwork2.ActionSupport;

import java.util.Arrays;
import java.util.Date;

public class Testi18nAction extends ActionSupport {
    private Date date = null;


    @Override
    public String execute() throws Exception {
        date = new Date();
        //在Action中訪問國際化資源文件的value值
        String username = getText("username");
        System.out.println(username);

        //訪問帶佔位符的
        String time = getText("time", Arrays.asList(date));
        System.out.println(time);
        return SUCCESS;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

}

struts.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
    <!-- 配置國際化資源文件 -->
    <constant name="struts.custom.i18n.resources" value="i18n"></constant>

    <package name="default" namespace="/" extends="struts-default">
        <action name="testi18nAction" class="com.cerr.struts2.i18n.app.Testi18nAction" method="execute">
            <result name="success">/i18n.jsp</result>
        </action>
    </package>
</struts>

i18n.jsp:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
  Created by IntelliJ IDEA.
  User: 白菜
  Date: 2019/8/6
  Time: 10:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <s:text name="time">
        <!-- value中的值爲值棧棧頂的屬性值-->
        <s:param value="date"></s:param>
    </s:text>
</body>
</html>


實現通過超鏈接切換語言

關鍵之處在於Struts2框架是如何確定Locale對象的,確定Locale對象的流程圖如下:


具體流程如下:

i18n攔截器在執行Action方法之前,自動查找請求中一個名爲request_locale的參數,如果該參數存在,攔截器就將其作爲參數,轉換成Locale對象,並將其設爲用戶默認的Locale(代表國家/語言環境),並把其設置爲sessionWW_TRANS_I18N_LOCALE屬性。

request沒有名爲request_locale的參數,則i18n攔截器會從Session中獲取WW_TRANS_I18N_LOCALE的屬性值,若該值不爲空,則將該屬性設置爲瀏覽器的默認的Locale

session中的WW_TRANS_I18N_LOCALE的屬性值爲空,則從ActionContext中獲取Locale對象。

要進行語言切換的話只要在超鏈接中傳遞一個request_locale參數即可,例如我們在上面的i18n.jsp中添加兩行代碼即可實現中英文切換:

<a href="testi18nAction.action?request_locale=en_US">English</a>|
<a href="testi18nAction.action?request_locale=zh_CN">中文</a>

值得注意的一定是超鏈接必須是一個Struts2的請求,因爲Struts2請求會使i18n攔截器不會工作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章