Spring MVC之LocaleResolver詳解

       對於LocaleResolver,其主要做用在於根據不一樣的用戶區域展現不一樣的視圖,而用戶的區域也稱爲Locale,該信息是能夠由前端直接獲取的。經過這種方式,能夠實現一種國際化的目的,好比針對美國用戶能夠提供一個視圖,而針對中國用戶則能夠提供另外一個視圖。本文主要講解若是使用LocaleResolver來實現對用戶不一樣視圖切換的目的。html

       LocaleResolver是Spring提供的一個接口,其聲明以下:前端

public interface LocaleResolver {
    // 根據request對象根據指定的方式獲取一個Locale,若是沒有獲取到,則使用用戶指定的默認的Locale
	Locale resolveLocale(HttpServletRequest request);
    
    // 用於實現Locale的切換。好比SessionLocaleResolver獲取Locale的方式是從session中讀取,但若是
    // 用戶想要切換其展現的樣式(由英文切換爲中文),那麼這裏的setLocale()方法就提供了這樣一種可能
	void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, 
        @Nullable Locale locale);
}

       針對LocaleResolver,Spring提供了幾種實現方式,分別以下:java

  • FixedLocaleResolver:在聲明該resolver時,須要指定一個默認的Locale,在進行Locale獲取時,始終返回該Locale,而且調用其setLocale()方法也沒法改變其Locale;
  • CookieLocaleResolver:其讀取Locale的方式是在session中經過Cookie來獲取其指定的Locale的,若是修改了Cookie的值,頁面視圖也會同步切換;
  • SessionLocaleResolver:其會將Locale信息存儲在session中,若是用戶想要修改Locale信息,能夠經過修改session中對應屬性的值便可;
  • AcceptHeaderLocaleResolver:其會經過用戶請求中名稱爲Accept-Language的header來獲取Locale信息,若是想要修改展現的視圖,只須要修改該header信息便可。

       須要說明的是,Spring雖然提供的幾個不一樣的獲取Locale的方式,但這些方式處理FixedLocaleResolver之外,其餘幾個也都支持在瀏覽器地址欄中添加locale參數來切換Locale。對於Locale的切換,Spring是經過攔截器來實現的,其提供了一個LocaleChangeInterceptor,在該攔截器中的preHandle()方法中,Spring會讀取瀏覽器參數中的locale參數,而後調用LocaleResolver.setLocale()方法來實現對Locale的切換。web

        這裏咱們以CookieLocaleResolver爲例來說解如何經過不一樣的Locale展現不一樣的視圖。首先是咱們的xml文件配置:spring

<context:component-scan base-package="mvc"/>

  <mvc:annotation-driven/>
  <mvc:interceptors>
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
    <bean class="mvc.interceptor.MyHandlerInterceptor"/>
  </mvc:interceptors>

  <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver"/>

  <bean id="localeResolver" 
        class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    <property name="defaultLocale" value="zh_CN"/>
  </bean>

       關於上述配置有三點須要說明:瀏覽器

  • 指定了使用的LocaleResolver爲CookieLocaleResolver,而且defaultLocale指定爲zh_CN,須要注意的是,Spring中LocaleResolver的bean名稱必須爲localeResolver,由於Spring讀取該bean時是經過該名稱讀取的;
  • 上述配置總還指定了ViewResolver爲ResourceBundleViewResolver,這裏不能使用InternalResourceViewResolver,由於其不支持經過不一樣的Locale進行不一樣的視圖切換,而ResourceBundleViewResolver是支持的;
  • 配置中添加了LocaleChangeInterceptor的攔截器,用於對Locale的切換,若是不須要Locale切換的功能,能夠不指定該攔截器。

       對於後臺接口的聲明,其與通常的接口聲明是沒有區別的。以下是咱們聲明的一個接口:cookie

@Controller
@RequestMapping("/user")
public class UserController {

  @Autowired
  private UserService userService;

  @RequestMapping(value = "/detail", method = RequestMethod.GET)
  public ModelAndView detail(@RequestParam("id") long id, 
       @ModelAttribute("message") String message, Locale locale) {
    System.out.println(message);
    ModelAndView view = new ModelAndView("user");
    User user = userService.detail(id);
    view.addObject("user", user);
    view.addObject("locale", locale);
    return view;
  }
}

       上述接口返回的視圖爲user,而且將當前用戶的Locale信息返回給了前端,能夠看到,這裏獲取Locale數據的方式就只須要簡單的聲明一個類型爲Locale的參數便可。session

       關於視圖的展現,因爲咱們須要根據不一樣的Locale展現不一樣的視圖,而在上述接口中,咱們暫時沒發現這樣的路由。實際上,這個路由是經過ResourceBundleViewResolver類實現的,在使用該ViewResovler時,其會到class路徑下查找名稱爲views的Resource Bundle,而且經過用戶指定的Locale,惟必定位到某個Resource Bundle。而後在該Resource Bundle中查找指定的視圖信息,好比這裏接口返回的視圖爲user,那麼就會在獲取到的Resource Bundle查找user.(class)和user.url信息,這裏user.(class)指定了展現該視圖所須要的View對象的,而user.url則指定了具體的視圖位置。好比以下配置的就是Locale分別爲zh_CN和en_US的視圖:mvc

# views_zh_CN.properties
user.(class)=org.springframework.web.servlet.view.InternalResourceView
user.url=/WEB-INF/view/user_zh_CN.jsp
# views_en_US.properties
user.(class)=org.springframework.web.servlet.view.InternalResourceView
user.url=/WEB-INF/view/user_en_US.jsp

       經過這種方式,ResourceBundleViewResolver就實現了針對不一樣的Locale來展現不一樣的視圖的目的。以下是咱們編寫的兩個分別用於zh_CN和en_US視圖展現的jsp頁面:app

<!-- user_zh_CN.jsp -->
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>User Jsp-zh CN</title>
</head>
<body>
${user.id}&nbsp;&nbsp;${user.name}&nbsp;&nbsp;${user.age}&nbsp;&nbsp;${locale}
</body>
</html>
<!-- user_en_US.jsp -->
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>User Jsp-en US</title>
</head>
<body>
${user.id}&nbsp;&nbsp;${user.name}&nbsp;&nbsp;${user.age}&nbsp;&nbsp;${locale}
</body>
</html>

       啓動上述程序,咱們在瀏覽器中鍵入http://localhost:8080/user/detail?id=1,能夠看到其展現了以下視圖:

1  Bob  27  zh_CN

       若是咱們添加名稱爲org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE,值爲en_US的cookie,那麼其展現的頁面切換以下:

1  Bob  27  en_US

       這說明咱們成功使用Cookie對Locale進行了切換。若是咱們在瀏覽器地址欄中添加locale=zh_CN的參數,能夠看到,頁面展現又切換爲了前面那種狀況。

       本文主要對LocaleResolver進行了講解,而且演示瞭如何經過配置不一樣的LocaleResolver來達到實現展現不一樣的視圖的目的。須要注意的是,咱們的LocaleResolver的bean名稱必須爲localeResolver,而且須要指定的ViewResolver輔以支持,不然切換的視圖可能沒法正常工做。

相關文章
相關標籤/搜索