有时候我可没需要国际化,比如开发一个需要提供中文和英文的网站,特别是比较有影响力的网站更是如此,如下图的农行,国际化一般分为语言、时区和国家信息等
首先熟悉一下Spring MVC的国际化结构。DispatcherServlet会解析一个LocaleResolver接口对象,通过它来决定用户区域(User Locale),解析出对应用户系统设定的语言或者用户选择的语言,以确定其国际化。LocaleResolver是一个接口,当DispatcherServlet初始化的时候会解析一个它的实现类,所以可以用它来进行国际化。该接口常用实现类:
- AcceptLanguageLocaleResolver:控制器无需写额外的内容,可以不用显示配置
- SessionLocaleResolver:使用Session传输语言环境,根据用户session的变量读取区域设置,它是可变的,如果session没有设置,那么它也会使用开发者设置的默认值
- CookieLocaleResolver:使用Cookie传送语言环境,根据Cookie数据获取国际化信息,如果用户禁止Cookie或者没有设置,它会根据accept-language HTTP头部确定默认区域
为了可以修改国际化,Spring MVC还提供了一个国际化的拦截器——LocaleChangeInterceptor,通过它可以获取参数,然后既可以通过CookieLocaleResolver使用浏览器的Cookie来实现国际化,也可以用SessionLocaleResolver通过服务器的Session来实现国际化。
1 指定国际化资源文件
在resources加入一下资源文件
message.properties:spring找不到对应的locale信息时加载的默认的资源文件
user.title=用户登录
user.name=用户名
user.password=密码
user.submit=登录
message_zh_CN.properties: 简体中文
user.title=用户登录
user.name=用户名
user.password=密码
user.submit=登录
message_zh_HK.properties: 繁体中文
user.title=用戶登陸
user.name=用戶名
user.password=密碼
user.submit=登陸
message_en_US.properties:英语-北美
user.title=User login
user.name=username
user.password=password
user.submit=login
2 MessageSource接口
MessageSource接口是Spring MVC为了加载消息所设置的接口,我们通过它来加载对应的国际化属性文件
使用ReloadableResourceBundleMessageSource去加载国家化资源文件,因为其可以在系统不重新启动的情况下重新加载属性文件,这样就可以在系统运行期修改对应的国际化文件,重新定制国际化的内容。
@Bean
public MessageSource messageSource(){
var messageSource = new ReloadableResourceBundleMessageSource();
//设置编码为UTF-8
messageSource.setDefaultEncoding("UTF-8");
//文件名为message,前缀为classpath,后缀通过Locale来决定
messageSource.setBasename("classpath:message");
//缓存1800秒(半小时),然后重新刷新
messageSource.setCacheSeconds(1800);
return messageSource;
}
注意:Bean的名称约定为messageSource,这是Spring默认的,不要随意修改,否则将找不到messageSource
3 指定语言区域解析器LocaleResovler,由它来确定使用哪个语言
@Bean
public LocaleResolver localeResolver(){
return new SessionLocaleResolver()
}
4 国际化的拦截器
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
}
5、提供Handler,用于切换Locale,进行测试
@RequestMapping("/locale/change")
public String locale(String language, HttpSession session){
//将接收到的参数信息封装成Locale设置到session中
Locale locale = null;
if(language == null){
locale = Locale.CHINA;
} else {
locale = new Locale(language.split("_")[0],language.split("_")[1]);
}
System.out.println(locale);
session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME,locale);
return "login";
}
6、使用spring mvc提供的标签库读取国际化资源
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="mvc" uri="http://www.springframework.org/tags" %>
<html>
<head>
<title><mvc:message code="user.title"/></title>
</head>
<body>
<a href="${pageContext.request.contextPath}/locale/change?language=zh_CN">简体中文</a>
<a href="${pageContext.request.contextPath}/locale/change?language=en_US">English</a>
<form action="" method="post">
<div>
<label><mvc:message code="user.name"/> :</label>
<input type="text" name="username"/>
</div>
<div>
<label><mvc:message code="user.password"/>:</label>
<input type="text" name="password"/>
</div>
<input type="submit" value='<mvc:message code="user.submit"/>'>
</form>
</body>
</html>
测试