SpringMVC 資源國際化實現以及常見問題


資源國際化可以很方便的實現web項目語言的切換,解決了web項目按需顯示不同語言界面的問題.

SpringMVC 的資源國際化基於JDK的java.util.ResourceBundle實現,經過SpringMVC的封裝實現起來非常簡單:

 

簡單實現具體步驟如下:

  1.在SpringMVC的配置文件中配置ResourceBundleMessageSource(該類的作用是綁定資源文件,根據Locale值不同,顯示不同的語言)

 1     <!-- 資源國際化相關配置 -->
 2     <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
 3         <!-- 如果在國際化資源文件中找不到對應代碼的信息,就用這個代碼作為名稱  -->
 4         <property name="useCodeAsDefaultMessage" value="true" />
 5         <!-- 默認編碼格式為 utf-8 -->
 6         <property name="defaultEncoding" value="UTF-8" />
 7         <!-- 國際化信息所在的文件名 --> 
 8         <property name="basenames">                    
 9             <list>
10                 <value>i18n.messages</value>
11             </list>
12         </property>
13     </bean>

           (PS:basenames屬性,值為資源文件的地址)

  2.配置LocaleResolver(該類指明了Locale應該存放在何處)

    LocaleResolver有三種選擇,分別是基於request,基於session,基於cookie,因為基於request的實現不支持手動切換,建議使用基於session的實現

    三種方式的配置具體如下:

     a.基於request的實現:

    <!-- 基於request實現資源國際化 -->
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver" />

                  b.基於session的實現:

    
    <!-- 基於Session實現資源國際化 -->
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
        <property name="defaultLocale" value="en"/>
    </bean>

       c.基於cookie的實現

    <!-- 基於cookie實現資源國際化 -->
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="en"/>
    </bean>

  3.配置localeChangeInterceptor攔截器(該類的作用是根絕不同的LocaleResolve采用不同的方式設置Locale)

    <mvc:interceptors>
        <bean id="localeChangeInterceptor"
            class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
            <property name="paramName" value="langType" />
        </bean>
    </mvc:interceptors>

  (paramName屬性,是指請求中 切換語言的參數名)

  4.編寫資源文件

    資源文件的命名規則是 basename [ _language ] [ _country ] [ _variant ].properties 

    languange country variant  需要為Locale類中的值

  5.頁面獲取資源文件中的值(以jsp為例)

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<spring:message code="comment.management" /> <!-- code的值為資源文件中對應的key -->

        6.頁面切換語言

      這種方式實現的資源國際化,會攔截所有的請求,只要請求中帶有 localeChangeInterceptor 中定義的參數,攔截器就會修改存儲的Locale,實現語言的切換

 

常見問題(重點):

  1.基於session不使用攔截器實現

    a.查看LocaleChangeInterceptor源碼,邏輯很簡單就是看看請求中是否有語言類型的參數,如果有新建一個Locale,然后從request中取出一個LocaleResolver ,然后執行setLocale()方法,

 

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws ServletException {

        String newLocale = request.getParameter(this.paramName);
        if (newLocale != null) {
            LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
            if (localeResolver == null) {
                throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?");
            }
            localeResolver.setLocale(request, response, StringUtils.parseLocaleString(newLocale));
        }
        // Proceed in any case.
        return true;
    }

 

    b.查看源碼,邏輯也很簡單就是將Locale屬性放到session中而已

    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
        WebUtils.setSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME, locale);
    }

    c.看到這里相信大伙應該心里有數啦,只要我們自己寫一個Controller,然后根據我們自定義的參數,自己生成Locale主動放入session中即可,這樣就可以去掉配置的攔截器

    @RequestMapping(value = "/changeLanguage", method = RequestMethod.POST)
    public @ResponseBody Language changeLanguage(HttpServletRequest request,
            @RequestParam(value = "langType", defaultValue = "zh") String langType) {

        // 獲取語言類型
        Language language = Language.getLanguage(langType);
        // 設置語言並放入session中
        Locale locale = new Locale(language.getLanguage(), language.getCountry());
        request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale);

        return language;
    }

 

 

  2.資源文件的加載順序

    a.不得不說這是一個比較坑的問題,首先看現象吧

      配置如下文件: 

        messages_en.properties 

        messages.properties 這里默認是中文

      當運行在中文環境下,切換按鈕沒有問題,語言可以正常的切換,

      當運行在英文環境下,切換按鈕失效,怎么點都是英文,此時我滿臉蒙蔽。

    b.問題原因,好吧,既然有問題就只能繼續研究唄,最后發現資源文件的加載順序如下:  


      baseName _ 指定的language _ 指定的country_ 指定的variant

      baseName _ 指定的language _ 指定的country

      baseName _ 指定的language

      baseName _默認的language _默認的country_默認的variant

      baseName _默認的language _默認的country

      baseName_默認的language

      baseName

      我們可以看出,加載順序為: 

      優先加載指定國際化內容,之后加載默認國際化內容,最后加載頂級文件

    c.解決方法在springMVC中配置LocaleResolve的時候指定默認語言(基於session,基於cookie)

 

    <!-- 基於cookie實現資源國際化 -->
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="en"/>
    </bean>

 

 

(以上,祝愉快!)

 

    

 

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM