本章承接前面的内容,继续讲述 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 设置部分:

能够看到,语言设置这一栏咱们把偏好语言设为英语(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 在工程已经生效。