本章承接前面的內容,繼續講述 LocaleResolver。php
LocalResolver 的做用是解析客戶的請求來自什麼地區,這樣就能夠針對請求中的地區信息,返回不一樣語言的視圖,以知足 Spring MVC 工程國際化的須要。而 LocalContextResolver 則繼承自 LocalResolver 接口,加入了對時區的支持。html
首先來看 LocalResolver 的默認配置(AcceptHeaderLocaleResolver)的源碼,該配置實現了 LocalResolver 的接口,而且重寫 resolveLocale 方法,使其能夠經過 Request 的 Header 字段解析請求的地區信息:前端
public class AcceptHeaderLocaleResolver implements LocaleResolver {
public AcceptHeaderLocaleResolver() {
}
public Locale resolveLocale(HttpServletRequest request) {
return request.getLocale();
}
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
throw new UnsupportedOperationException("Cannot change HTTP accept header - use a different locale resolution strategy");
}
}
複製代碼
能夠看到,這裏 resolveLocale 方法直接去拿了請求中的 locale 字段,查看客戶端這邊最支持哪一種語言。而且該類不支持 set 方法。java
首先,咱們須要配置三個對應語言的 resource 文件,在 resources/locales 文件夾下分別建立 locale_en.properties, locale_en_US.properties, locale_zh_CN.properties 文件,注意直接建立這三個文件後 Intellij 會把它合到一個文件夾裏面(這裏應該會變成一個名爲 locale 文件夾)。properties 文件內的代碼分別是:web
# locale_en.properties 文件
message.locale=en_hello
複製代碼
# locale_en_US.properties 文件
message.locale=en_US_hello
複製代碼
# locale_zh_CN.properties 文件
message.locale=zh_CN_hello
複製代碼
在 root-context 配置 LocalResolver 的 bean,而且配置對應的國際化資源文件 ReloadableResourceBundleMessageSource,其中的方法能夠針對輸入的 Locale 對象去獲取對應的 resource 文件:spring
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<context:component-scan base-package="com.test.myapp.example"/>
<!-- 其他 bean 配置 -->
<!--LocaleResolver 配置-->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver">
</bean>
<!-- 國際化資源文件 -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 若是資源文件放在classpath下,basename的value必須有classpath:前綴,不然報錯:No message found under code... -->
<!-- 這個地方 value 是紅色也沒問題,Spring MVC 在運行的時候仍是會找到這些資源文件 -->
<property name="basename" value="classpath:locales/locale" />
<!-- 若是在國際化資源文件中找不到對應代碼的信息,就用這個代碼做爲名稱返回 -->
<!--<property name="useCodeAsDefaultMessage" value="true" />-->
<!--<property name="defaultEncoding" value="ISO-8859-1"/>-->
</bean>
<!-- 其他 bean 配置 -->
</beans>
複製代碼
而後就是爲咱們的 LocaleResolver 配置一個接口,該接口的功能是獲取發出當前的客戶端支持哪些語言,而且最爲偏好的語言是什麼,以後再去獲取對應的 properties 文件中的信息。chrome
@Controller
public class LocaleResolverController {
@RequestMapping(value="/accept-header-resolver.do", method = RequestMethod.GET)
public ModelAndView resolveLocale(HttpServletRequest request) {
String clientLocale = "";
// 獲取客戶端支持的語言
Enumeration<Locale> locales = request.getLocales();
while (locales.hasMoreElements()) {
Locale locale = locales.nextElement();
clientLocale += locale + ",";
}
RequestContext requestContext = new RequestContext(request);
// 獲取對應地區的 properties 中的信息
String value = requestContext.getMessage("message.locale");
ModelAndView modelAndView = new ModelAndView("localeResolver");
modelAndView.addObject("clientLocale", clientLocale);
modelAndView.addObject("currentLocale", requestContext.getLocale());
modelAndView.addObject("localeResource", value);
return modelAndView;
}
}
複製代碼
上述代碼中 clientLocale
表示客戶端瀏覽器支持的語言,currentLocale
則是客戶端的偏好語言,value
則表示根據客戶端偏好語言取回的對應語言 properties 中的字段值。瀏覽器
上面測試接口返回的是一個 ModelAndView 對象,所以,咱們還須要 jsp 前端文件,來輸出上述的字段:bash
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>locale resolver page</title>
</head>
<body>
<p>
客戶端支持:${clientLocale} 客戶端當前地區:${currentLocale}, 服務端對應內容:${localeResource}
</p>
</body>
</html>
複製代碼
咱們已經完成了具體代碼的編寫,下面進入測試。app
此次測試以 chrome 爲例,首先查看 chrome 設置部分:
![chrome 語言設置](/Users/shenruofan/Desktop/屏幕快照 2018-11-06 下午4.32.43.png)
能夠看到,語言設置這一欄咱們把偏好語言設爲英語(EN)。運行工程後,在瀏覽器中輸入:http://localhost:8080/accept-header-resolver.do,咱們會看到以下的標識:
客戶端支持:en,zh,en_US,zh_CN, 客戶端當前地區:en, 服務端對應內容:en_hello
複製代碼
以後,咱們在語言設置中把中文(簡體)(zh_CN)放在語言偏好的第一位,再輸入相同的地址,則會出現以下的標識:
客戶端支持:zh_CN,zh,en,en_US, 客戶端當前地區:zh_CN, 服務端對應內容:zh_CN_hello
複製代碼
這能夠說明,咱們的 LocaleResolver 在工程已經生效。