<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-314  評論-209  文章-0  trackbacks-0
    因為希望把SpringSide搞成國際化項目,i18n就成了必做的事情。
    照抄appfuse,折騰了很久后才發現appfuse式的sample總是只顧著演示自己的一畝三分地而忽略了很多其他東西。

       1.從基礎開始,沒有Spring時,Java的i18n是這樣的:
       1.1 jsp環境
        首先寫一個messages.zh_CN.properties文件,放在class-path也就是/WEB-INF/classes里     welcome=歡迎    然后用native2ascii.exe把它轉為 welcome=\u6b22\u8fce
        在web.xml中定義messages文件     
           <context-param>
                <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
                <param-value>messages</param-value>
            </context-param>
        最后在jsp里使用
    <%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>
    <fmt:message key="welcome"/>
    如果有多個Resource Bundle文件, 就要在jsp里用<ftm:bundle>定義了.

    1.2 pure Java環境
        ResourceBundle rb = ResourceBundle.getBundle("messages");
        String welcome = rb.getString("welcome");

    2.Spring的增強及appfuse的做法
       Spring增加了MessageSource的概念,一是ApplicationContext將充當一個單例的角色,不再需要每次使用i18時都初始化一次ResourceBundle,二是可以代表多個Resource Bundle.

       在ApplicationContext的定義文件中,增加如下節點: 
       <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
            <property name="basename" value="messages"/>
        </bean>
       則在pure java環境中。  context.getMessage("welcome", null, Locale.CHINA)

      而在jsp環境中,Controller調用JSTL viewResolver再調用Jsp時,<fmt:message>將繼續發揮它的功效。

      因此,appfuse等sample都是在appfuse-servlet.xml 中定義一個<messageSource>。

    3.Better Practice
    3.1 要不要定義javax.servlet.jsp.jstl.fmt.localizationContext[定義]
          Appfuse等sample,都是假定大家完全使用Controller作訪問入口,jsp甚至藏在了/web-inf/中。而很不幸,大家的項目可能還是有很多直接訪問jsp的地方,而直接訪問jsp時,<messageSource>節點是沒有作用的。
         但如果定義了javax...localizationContext, 又會讓MessageSource失效......


    3.2 messageSource定義在ApplicationContext.xml還是appfuse-servlet.xml
         ApplicationContext*.xml由ContextLoaderListener載入而appfuse-servlet.xml靠dispatchServlet載入并擁有一個指向ApplcationContex*.xml指針。所以,appfuse-servlet.xml能看到定義在ApplcationContext里的東西,而反之做不到。
         明顯, 把<messageSource>定義在ApplicationContext.xml 能獲得更好的可見性。
         但是appfuse沒有在pure Java代碼中使用i18n,也就沒有考慮這個問題。

    3.3 堅決不用雞肋級<spring:message> tag
          連appfuse也不用它,可見多么雞肋。因為fmt在找不到資源時,最多顯示???welcome???,而<spring:message>則會拋出異常,誰會喜歡這種定時炸彈阿。

    3.4 有趣的theme 解決"做成圖片的文字"的國際化
           theme也就是把message的原理發揮了一下,讓不同語言的美術字圖片的路徑也可以定義在theme_zh_CN.properties和theme_en_US.properties中。終于有一個不那么雞肋的spring tag了。

    4.簡單歸納

    1. jstl中仍然使用標準的<ftm:message>及其定義?

    2.java中使用spring的<messageSource>實現單例

    3.用<spring:theme>解決那些做成圖片的文字的國際化問題

    4.Spring 還有session,cookie locale resolver, 到時可以看一下.

    posted on 2008-11-22 16:40 xzc 閱讀(1473) 評論(3)  編輯  收藏 所屬分類: Java

    評論:
    # re: Spring i18n的better practice(相對于appfuse) 2008-11-22 16:46 | xzc
    <%@page contentType="text/html; charset=UTF-8"%>
    <%@page import="java.util.*"%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x"%>
    <html>
    <head>
    <title>language choose</title>
    </head>
    <body bgcolor="#ffffff">

    copyright @ lizongbo @ donews.net


    <c:if test="${param['locale'] != null}">
    <fmt:setLocale value="${param['locale']}" scope="session"/>
    <fmt:setTimeZone value="${param['locale']}" scope="session"/>
    </c:if>
    <c:if test="${param['locale'] == null}">
    <fmt:setLocale value="${header['locale']}" scope="session"/>
    <fmt:setTimeZone value="${header['locale']}" scope="session"/>
    </c:if>
    <%
    Locale crtl = Locale.getDefault();
    Object cobj = session.getAttribute("javax.servlet.jsp.jstl.fmt.locale.session");
    if (cobj != null && cobj instanceof Locale) {
    crtl = (Locale) cobj;
    }
    Locale[] la = java.text.NumberFormat.getAvailableLocales();
    %>
    <form method="POST" action="">
    language choose:
    <br />
    <select name="locale">
    <%for (int i = 0; i < la.length; i++) {%>
    <option value="<%=la[i]%>" <%if (la[i].equals(crtl)) {
    out.print("selected=\"selected\"");
    }%>><%= la[i].getDisplayName(crtl)%></option>
    <%
    }
    %>
    </select>
    <br />
    <input type="submit" value="change"/>
    </form>
    </body>
    </html>


      回復  更多評論
      
    # re: Spring i18n的better practice(相對于appfuse) 2008-11-22 16:47 | xzc
    使用JSTL解決國際化問題非常簡單,首先在WEB-INF/classes放上資源文件,例如messages.properties、messages_zh_CN.properties等文件。

    使用JSTL fmt庫:
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
    <fmt:setLocale value="${header['accept-language']}"/>
    <fmt:setBundle basename="messages"/>

    setLocale設置地區,一般從HTTP Header里面取就比較方便一點。
    setBundle設置資源文件的名稱。

    通過如下方式就可以應用了。
    <fmt:message key="SampleMessage"/>

    還可以加參數。
    <fmt:message key="LoginMessage">
    <fmt:param value="${loginName}"/>
    </fmt:message>  回復  更多評論
      
    # re: Spring i18n的better practice(相對于appfuse) 2008-11-22 16:59 | xzc
    9.5 I18N formatting 標簽庫
    看到 I18N 就應該想到知識“國際化”, I18N formatting 標簽庫就是用于在 JSP 頁面中做國際化的動作。在該標簽庫中的標簽一共有 12 個,被分為了兩類,分別是:

    q 國際化核心標簽: <fmt:setLocale> 、 <fmt:bundle> 、 <fmt:setBundle> 、 <fmt:message> 、 <fmt:param> 、 <fmt:requestEncoding> 。

    q 格式化標簽: <fmt:timeZone> 、 <fmt:setTimeZone> 、 <fmt:formatNumber> 、 <fmt:parseNumber> 、 <fmt:formatDate> 、 <fmt:parseDate> 。

    下面只選擇其中常見的一些標簽和屬性進行介紹。

    9.5.1 用于設置本地化環境的 <fmt:setLocale> 標簽
    <fmt:setLocale> 標簽用于設置 Locale 環境。它的屬性和描述如表 9.17 所示:

    表 9.17   <fmt:setLocale> 標簽屬性和說明

    屬性
    描述

    value
    Locale 環境的指定,可以是 java.util.Locale 或 String 類型的實例

    scope
    Locale 環境變量的作用范圍(可選)


    下面看一個示例:

    <fmt:setLocale value="zh_TW"/>

    表示設置本地環境為繁體中文。

    9.5.2 用于資源文件綁定的 <fmt:bundle> 、 <fmt:setBundle> 標簽
    這兩組標簽用于資源配置文件的綁定,唯一不同的是 <fmt:bundle> 標簽將資源配置文件綁定于它標簽體中的顯示, <fmt:setBundle> 標簽則允許將資源配置文件保存為一個變量,在之后的工作可以根據該變量來進行。

    根據 Locale 環境的不同將查找不同后綴的資源配置文件,這點在國際化的任何技術上都是一致的,通常來說,這兩種標簽單獨使用是沒有意義的,它們都會與 I18N formatting 標簽庫中的其他標簽配合使用。它們的屬性和描述如表 9.18 所示:

    表 9.18   <fmt:bundle> 、 <fmt:setBundle> 標簽屬性和說明

    屬性
    描述

    basename
    資源配置文件的指定,只需要指定文件名而無須擴展名,二組標簽共有的屬性

    var
    <fmt:setBundle> 獨有的屬性,用于保存資源配置文件為一個變量

    scope
    變量的作用范圍


    下面看一個示例

    <fmt:setLocale value="zh_CN"/>

    <fmt:setBundle basename="applicationMessage" var="applicationBundle"/>

    該示例將會查找一個名為 applicationMessage_zh_CN.properties 的資源配置文件,來作為顯示的 Resource 綁定。

    9.5.3 用于顯示資源配置文件信息的 <fmt:message> 標簽
    用于信息顯示的標簽,將顯示資源配置文件中定義的信息。它的屬性和描述如表 9.19 所示:

    表 9.19   <fmt:message> 標簽屬性和說明

    屬性
    描述

    key
    資源配置文件的“鍵”指定

    bundle
    若使用 <fmt:setBundle> 保存了資源配置文件,該屬性就可以從保存的資源配置文件中進行查找

    var
    將顯示信息保存為一個變量

    scope
    變量的作用范圍


    下面看一個示例:

    <fmt:setBundle basename="applicationMessage" var="applicationBundle"/>

    <fmt:bundle basename="applicationAllMessage">

    <fmt:message key="userName" />

    <p>

    <fmt:message key="passWord" bundle="${applicationBundle}" />

    </fmt:bundle>

    該示例使用了兩種資源配置文件的綁定的做法,“ applicationMessage ”資源配置文件利用 <fmt:setBundle> 標簽被賦于了變量“ applicationBundle ”,而作為 <fmt:bundle> 標簽定義的“ applicationAllMessage ”資源配置文件作用于其標簽體內的顯示。

    q 第一個 <fmt:message> 標簽將使用“ applicationAllMessage ”資源配置文件中“鍵”為“ userName ”的信息顯示。

    q 第二個 <fmt:message> 標簽雖然被定義在 <fmt:bundle> 標簽體內,但是它使用了 bundle 屬性,因此將指定之前由 <fmt:setBundle> 標簽保存的“ applicationMessage ”資源配置文件,該“鍵”為“ passWord ”的信息顯示。

    9.5.4 用于參數傳遞的 <fmt:param> 標簽
    <fmt:param> 標簽應該位于 <fmt:message> 標簽內,將為該消息標簽提供參數值。它只有一個屬性 value 。

    <fmt:param> 標簽有兩種使用版本,一種是直接將參數值寫在 value 屬性中,另一種是將參數值寫在標簽體內。

    9.5.6 用于為請求設置字符編碼的 <fmt:requestEncoding> 標簽
    <fmt:requestEncoding> 標簽用于為請求設置字符編碼。它只有一個屬性 value ,在該屬性中可以定義字符編碼。

    9.5.7 用于設定時區的 <fmt:timeZone> 、 <fmt:setTimeZone> 標簽
    這兩組標簽都用于設定一個時區。唯一不同的是 <fmt:timeZone> 標簽將使得在其標簽體內的工作可以使用該時區設置, <fmt:setBundle> 標簽則允許將時區設置保存為一個變量,在之后的工作可以根據該變量來進行。它們的屬性和描述如表 9.20 所示:

    表 9.20   <fmt:timeZone> 、 <fmt:setTimeZone> 標簽 屬性和說明

    屬性
    描述

    value
    時區的設置

    var
    <fmt:setTimeZone> 獨有的屬性,用于保存時區為一個變量

    scope
    變量的作用范圍


    9.5.8 用于格式化數字的 <fmt:formatNumber> 標簽
    <fmt: formatNumber > 標 簽用于格式化數字。它的屬性和描述如表 9.21 所示:

    表 9.21   <fmt:formatNumber> 標簽屬性和說明

    屬性
    描述

    value
    格式化的數字,該數值可以是 String 類型或 java.lang.Number 類型的實例

    type
    格式化的類型

    pattern
    格式化模式

    var
    結果保存變量

    scope
    變量的作用范圍

    maxIntegerDigits
    指定格式化結果的最大值

    minIntegerDigits
    指定格式化結果的最小值

    maxFractionDigits
    指定格式化結果的最大值,帶小數

    minFractionDigits
    指定格式化結果的最小值,帶小數


    <fmt:formatNumber> 標簽實際是對應 java.util.NumberFormat 類, type 屬性的可能值包括 currency (貨幣)、 number (數字)和 percent (百分比)。

    下面看一個示例。

    <fmt:formatNumber value="1000.888" type="currency" var="money"/>

    該結果將被保存在“ money ”變量中,將根據 Locale 環境顯示當地的貨幣格式。


    9.5.9 用于解析數字的 <fmt:parseNumber> 標簽
    <fmt:parseNumber> 標簽用于解析一個數字,并將結果作為 java.lang.Number 類的實例返回。 <fmt:parseNumber> 標簽看起來和 <fmt:formatNumber> 標簽的作用正好相反。它的屬性和描述如表 9.22 所示:

    表 9.22   <fmt:parseNumber> 標簽屬性和說明

    屬性
    描述

    value
    將被解析的字符串

    type
    解析格式化的類型

    pattern
    解析格式化模式

    var
    結果保存變量,類型為 java.lang.Number

    scope
    變量的作用范圍

    parseLocale
    以本地化的形式來解析字符串,該屬性的內容應為 String 或 java.util.Locale 類型的實例


    下面看一個示例。

    <fmt:parseNumber value="15%" type="percent" var="num"/>

    解析之后的結果為“ 0.15 ”。

    9.5.10 用于格式化日期的 <fmt:formatDate> 標簽
    <fmt:formatDate> 標簽用于格式化日期。它的屬性和描述如表 9.23 所示:

    表 9.23   <fmt:formatDate> 標簽屬性和說明

    屬性
    描述

    value
    格式化的日期,該屬性的內容應該是 java.util.Date 類型的實例

    type
    格式化的類型

    pattern
    格式化模式

    var
    結果保存變量

    scope
    變量的作用范圍

    timeZone
    指定格式化日期的時區


    <fmt:formatDate> 標簽與 <fmt:timeZone> 、 <fmt:setTimeZone> 兩組標簽的關系密切。若沒有指定 timeZone屬性, 也可以通過 <fmt:timeZone> 、 <fmt:setTimeZone> 兩組標簽設定的時區來格式化最后的結果。

    9.5.11 用于解析日期的 <fmt:parseDate> 標簽
    <fmt:parseDate> 標簽用于解析一個日期,并將結果作為 java.lang.Date 類型的實例返回。 <fmt:parseDate> 標簽看起來和 <fmt:formatDate> 標簽的作用正好相反。它的屬性和描述如表 9.24 所示:

    表 9.24   <fmt:parseDate> 標簽屬性和說明

    屬性
    描述

    value
    將被解析的字符串

    type
    解析格式化的類型

    pattern
    解析格式化模式

    var
    結果保存變量,類型為 java.lang.Date

    scope
    變量的作用范圍

    parseLocale
    以本地化的形式來解析字符串,該屬性的內容為 String 或 java.util.Locale 類型的實例

    timeZone
    指定解析格式化日期的時區


    <fmt:parseNumber> 和 <fmt:parseDate> 兩組標簽都實現解析字符串為一個具體對象實例的工作,因此,這兩組解析標簽對 var 屬性的字符串參數要求非常嚴格。就 JSP 頁面的表示層前段來說,處理這種解析本不屬于份內之事,因此 <fmt:parseNumber> 和 <fmt:parseDate> 兩組標簽應該盡量少用,替代工作的地方應該在服務器端表示層的后段,比如在 Servlet 中。

      回復  更多評論
      
    主站蜘蛛池模板: 亚洲精品无码成人AAA片| 国产免费爽爽视频免费可以看| 中文字幕亚洲激情| 亚洲高清免费视频| 中文字幕久久亚洲一区| 久草免费福利在线| 亚洲精品无码午夜福利中文字幕 | 国产精品亚洲专区无码唯爱网| 天天摸天天操免费播放小视频| 亚洲依依成人亚洲社区| 超pen个人视频国产免费观看| 亚洲大码熟女在线观看| 国产不卡免费视频| 一个人看的www免费高清| 精品久久久久久亚洲| 免费h视频在线观看| 亚洲精品在线播放| 免费观看的毛片手机视频| 国产精品亚洲专一区二区三区| 亚洲精品视频在线看| 日本免费污片中国特一级| 日韩精品亚洲人成在线观看 | 国产亚洲A∨片在线观看| 免费人成黄页在线观看日本| 2022年亚洲午夜一区二区福利| 欧美最猛性xxxxx免费| 黄页网站在线视频免费| 国产v亚洲v天堂无码网站| 五月亭亭免费高清在线| 亚洲1区2区3区精华液| 亚洲日韩v无码中文字幕| 91免费播放人人爽人人快乐| 丰满亚洲大尺度无码无码专线| 国产成人A亚洲精V品无码| 国产成人yy免费视频| MM1313亚洲国产精品| 亚洲国产精华液网站w| 无人影院手机版在线观看免费| 一个人免费观看日本www视频| 亚洲美女视频网站| 亚洲成人影院在线观看|