概述
Spring MVC为我们提供国际化支持,通过设置系统的环境,根据运行环境使用不同的语言显示。
Spring提供LocaleResolver接口的作用是解析客户端使用的地区(Locale),目的是为了根据这些信息实现视图多语言即国际化。
LocaleContextResolver接口继承LocaleResolver接口,增加时区(TimeZone)支持。
解析器(默认AcceptHeaderLocaleResolver)
AcceptHeaderLocaleResolver解析器implements LocaleResolver接口,重写resolverLocale(HttpServletRequest request)方法,通过检查客户端发送请求中的Accept-Language头来确定客户端Locale(地区信息)。
此解析器不支持程序设置Locale,只能通过改变客户端Accept-Language头信息来改变设置,核心源码如下:
/**
* 从当前的request中解析Locale
*/
@Override
public Locale resolveLocale(HttpServletRequest request) {
// 获取默认设置,可在配置AcceptHeaderLocaleResolver Bean中设置defaultLocale属性
Locale defaultLocale = getDefaultLocale();
// 设置了默认值并且请求中没有Accept-Language头信息时,使用默认设置
if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
return defaultLocale;
}
// 从当前请求中获取Locale
Locale requestLocale = request.getLocale();
// 从配置中获取支持的Locale集合,可在AcceptHeaderLocaleResolver Bean中设置supportedLocales属性
List<Locale> supportedLocales = getSupportedLocales();
// 未设置supportedLocales或者supportedLocales中包括请求Locale,则使用请求Locale
if (supportedLocales.isEmpty() || supportedLocales.contains(requestLocale)) {
return requestLocale;
}
// 找到设置的Locale集合中是否有请求的Locale
Locale supportedLocale = findSupportedLocale(request, supportedLocales);
if (supportedLocale != null) {
return supportedLocale;
}
return (defaultLocale != null ? defaultLocale : requestLocale);
}
/**
* 不支持程序设置Locale
*/
@Override
public void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale) {
throw new UnsupportedOperationException(
"Cannot change HTTP accept header - use a different locale resolution strategy");
}
实战
- 项目结构
- 配置文件
在Spring MVC配置文件中配置资源加载以及AcceptHeaderLocaleResolver Bean,配置如下:
<!-- 国际化资源文件 -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 如果资源文件放在classpath下,basename的value必须有classpath:前缀,否则报错:No message found under code... -->
<property name="basename" value="classpath:i18n/messages" />
<!-- 如果在国际化资源文件中找不到对应代码的信息,就用这个代码作为名称返回 -->
<property name="useCodeAsDefaultMessage" value="true" />
<!--<property name="defaultEncoding" value="ISO-8859-1"/>-->
</bean>
<!-- LocaleResolver解析器 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver">
<property name="defaultLocale" value="zh_CN"/>
</bean>
- 属性文件
在类路径下创建配置文件,本项目放置路径为:resources/i18n/messages_*.proerties,详见项目结构,配置文件中配置信息如下:
messages_en.properties
message.locale=en
messages_en _US.properties
message.locale=en_US
messages_zh _CN.properties
message.locale=zh_CN
- 控制器
编写Controller控制器,以便测试,代码如下:
@GetMapping(value = "/acceptHeaderLocaleResolver" , produces = "text/html;charset=UTF-8")
@ResponseBody
public String test(HttpServletRequest request) {
String clientLocale = "";
Enumeration<Locale> enus = request.getLocales();
while (enus.hasMoreElements()){
Locale locale = enus.nextElement();
clientLocale += locale + ",";
}
RequestContext requestContext = new RequestContext(request);
String value = requestContext.getMessage("message.locale");
return "客户端支持的Locale有:"+clientLocale+" </br>当前使用的Locale是:" + requestContext.getLocale() + " </br>使用的资源Locale文件是:" + value ;
}
- 测试
以chrome为例,首先确认chrome的语言设置,如下:
有上图可见,测试的第一语言为中文(简体),我们在地址栏访问我们的Controller,返回信息如下:
由于客户端设置的为zh-CN,Spring MVC国际化使用的属性文件是messages_zh _CN.properties,我们通过修改客户端属性进行测试,调整chrome语言,即把英语设置到第一位,再次访问Controller,返回信息如下:
此时的系统使用语言已经切换为message_en.properties。
总结
- 各浏览器默认的语言各不相同,可通过设置进行修改调整;
- 客户端请求头Accept-Languages的第一个(权重最大)为Spring MVC使用的Locale;
- 权重最大的Locale名必须与属性文件一致,否则找不到,如Accept-Languages的第一个为en,则资源文件名必须设置为messages_en.properties,如果第一个是zh-CN,则资源名称为messages_zh _CN.properties;
- 使用messageSource Bean时,如果资源文件放在类路径下,basename的值必须以classpath:开头。
最后创建了qq群方便大家交流,可扫描加入,同时也可加我qq:276420284,共同学习、共同进步,谢谢!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。