1. 程式人生 > >SpringMVC國際化中的localeResolver介面!

SpringMVC國際化中的localeResolver介面!

為了讓web應用程式支援國際化,必須識別每個使用者的首選區域,並根據這個區域顯示內容。

在Spring MVC應用程式中,使用者的區域是通過區域解析器來識別的,它必須實現LocaleResolver介面。Spring MVC提供了幾個LocaleResolver實現,讓你可以按照不同的條件來解析區域。除此之外,你還可以實現這個介面,建立自己的區域解析器。

要定義一個區域解析器,只需在web應用程式上下文中註冊一個LocaleResolver型別的Bean就可以了。你必須將區域解析器的Bean名稱設定為localeResolver,這樣DispatcherServlet才能自動偵測到它。請注意,每DispatcherServlet只能註冊一個區域解析器。

1.按HTTP請求頭部解析區域

Spring採用的預設區域解析器是AcceptHeaderLocaleResolver。它通過檢驗HTTP請求的accept-language頭部來解析區域。這個頭部是由使用者的web瀏覽器根據底層作業系統的區域設定進行設定。請注意,這個區域解析器無法改變使用者的區域,因為它無法修改使用者作業系統的區域設定。

2.按會話屬性解析區域

解析區域的另一種方法是通過SessionLocaleResolver。它通過檢驗使用者會話中預置的屬性來解析區域。如果該會話屬性

不存在,它會根據accept-language HTTP頭部確定預設區域。

Xml程式碼  收藏程式碼
  1. <bean id="localeResolver" class="org.springframewrok.web.servlet  
  2.     .i18n.SessionLocaleResolver">  
  3.     <property name="defaultLocale" value="en"/>  
  4. </bean>  

如果會話屬性不存在,可以為這個解析器設定defaultLocale屬性。請注意,通過修改儲存該區域的會話屬性,這個區域

解析器可以改變使用者的區域設定。

3.按Cookie解析區域

你也可以檢驗使用者瀏覽器中的Cookie,用CookieLocaleResolver

來解析區域。如果Cookie不存在,它會根據accept-language HTTP頭部確定預設區域。 

Xml程式碼  收藏程式碼
  1. <bean id="localeResolver" class="org.springframework.web.servlet  
  2.     .i18n.CookieLocaleResolver"/>  

這個區域解析器所採用的Cookie可以通過cookieName和cookieMaxAge屬性進行定製。cookieMaxAge屬性表示這個Cookie應該持續多少秒,-1表示這個Cookie在瀏覽器關閉之後就失效。 

Xml程式碼  收藏程式碼
  1. <bean id="localeResolver" class="org.springframework.web.servlet  
  2.     .i18n.CookieLocaleResolver">  
  3.     <property name="cookieName" value="language"/>  
  4.     <property name="cookieMaxAge" value="3600"/>  
  5.     <property name="defaultLocale" value="en"/>  
  6. </bean>     
如果使用者瀏覽器中不存在該Cookie,你也可以為這個解析器設定defaultLocale屬性。通過修改儲存該區域的Cookie,這個區域解析器能夠改變使用者的區域。

4.FixedLocaleResolver 

 一直使用固定的Local, 改變Local 是不支援的 。

5.修改使用者的區域

除了顯式呼叫LocaleResolver.setLocale()來修改使用者的區域之外,還可以將LocaleChangeInterceptor攔截器應用到處理程式對映中,它會發現當前HTTP請求中出現的特殊引數。其中的引數名稱可以通過攔截器的paramName屬性進行自定義。如果這種引數出現在當前請求中,攔截器就會根據引數值來改變使用者的區域。

Xml程式碼  收藏程式碼
  1. <beans...>  
  2.     ...  
  3.     <bean id="localeChangeInterceptor"  
  4.         class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">  
  5.         <property name="paramName" value="language"/>  
  6.     </bean>  
  7.     <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  
  8.         <property name="interceptors">  
  9.             <list>  
  10.                 ...  
  11.                 <ref bean="localeChangeInterceptor"/>  
  12.             </list>  
  13.         </property>  
  14.     </bean>  
  15.     <bean class="org.springframework.web.servlet.mvc.support  
  16.         .ControllerClassNameHandlerMapping">  
  17.         <property name="interceptors">  
  18.             <list>  
  19.                 ...  
  20.                 <ref bean="localeChangeInterceptor"/>  
  21.             </list>  
  22.         </property>  
  23.     </bean>  
  24. <beans>  

LocaleChangeInterceptor只能為啟用了它的那些處理程式對映偵測引數。因此,如果web應用程式上下文中配置了不止一個處理程式對映,就必須在所有處理程式對映中註冊這個攔截器,以便能在任意URL中改變它們的區域設定。

現在,利用language引數,可以通過任意URL修改使用者的區域。例如,下面兩個URL分別將使用者的區域語言改成了美式

英語和德語。 

Java程式碼  收藏程式碼
  1. http://localhost:8080/court/welcome.htm?language=en_US  
  2. http://localhost:8080/court/welcome.htm?language=de  
6.使用Spring MVC時,  controller如何得到請求的 Local

DispatchServlet 會在 processRequest(HttpServletRequest request, HttpServletResponse response) 方法中設定LocaleContext, 把LocalContext 和當前執行緒關聯起來. 程式碼如下:

  1. LocaleContextHolder.setLocaleContext (buildLocaleContext(request), this. threadContextInheritable );  

DispatchServlet 中buildLocalContext程式碼如下:

  1. protected LocaleContext buildLocaleContext( final HttpServletRequest request) {  
  2.         returnnew LocaleContext() {  
  3.             public Locale getLocale() {  
  4.                 return localeResolver .resolveLocale(request);  
  5.             }  
  6.             @Override
  7.             public String toString() {  
  8.                 return getLocale().toString();  
  9.             }  
  10.         };  
  11. }  

這裡的Local通過localResolver 解析得到,  localResolver 即是從Spring 配置檔案配置的localResolver, 預設是"AcceptHeaderLocaleResolver".

如果你想要在 controller 中得到當前請求的Local,  程式碼可以如下寫:

  1. Locale locale = LocaleContextHolder.getLocale();  

或者你可以用Spring 中的RequestContextUtils 類方法getLocal得到 request 中儲存的localResolver, 並用localResolver 解析得到Local.   程式碼如下:

  1. publicstatic Locale getLocale (HttpServletRequest request) {  
  2.         LocaleResolver localeResolver = getLocaleResolver (request);  
  3.         if (localeResolver != null ) {  
  4.             return localeResolver.resolveLocale(request);  
  5.         }  
  6.         else {  
  7.             return request.getLocale();  
  8.         }  
  9. }  

localResolver 會在DispatcherServlet的doService 方法中,將localResolver儲存到request 屬性中 程式碼如下:

  1. request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);