Spring Boot国际化配置过程
Spring MVC中提供了MessageSource国际化消息源机制,其主要作用为装载国际化消息。这里一般使用JDK的ResourceBundleMessageSource进行处理,在设置国际化时,这里无需配置。
Spring Boot中默认使用的国际化配置文件为messages.properties,该文件在开启国际化时必须创建,否则Spring MVC将不启用国际化消息机制。但该文件的名称可以进行自定义(后续会说明)。此外,中文配置文件和英文配置文件名如下:
- messages_zh_CN.properties
- messages_en_US.properties
Spring MVC中提供的国际化解析器(用于解析用户使用的国际区域是哪里)包含如下几个:
- AcceptHeaderLocaleResolver:根据浏览器的请求头来确定国际化区域
- FixedLocaleResolver:设置固定的国际化区域
- CookieLocaleResolver:使用cookie设置国际化区域
- SessionLocaleResolver :使用session设置国际化区域
当使用AcceptHeaderLocaleResolver或FixedLocaleResolver来实现国际化的时候,只需要在application.properties配置文件中进行如下的相关设置,既可以实现国际化,无需其他的开发工作:
# 指定国际化区域,可以覆盖Accept-Language请求头信息
spring.mvc.locale=
# 国际化解析器,可以选择fixed或accpet-header
# fixed代表固定的国际化区域,accept-header表示读取浏览器的Accept-Language请求头信息
spring.mvc.locale-resolver=accept-header
使用SessionLocaleResolver实现国际化
当使用session和cookie来实现国际化时比较类似,这里以session为例实现国际化。
1. 配置国际化消息
在application.properties配置文件中进行如下配置:
# Spring MVC国际化配置
# 设置文件编码
spring.messages.encoding=UTF-8
# 国际化文件基础名称
spring.messages.basename=international
# 国际化消息缓存有效时间(单位为秒),超时将重新载入
spring.messages.cache-duration=3600
划重点,其中spring.messages.basename配置项即为指定国际化配置文件所在的目录和名称,即不再使用默认的messages名称,而是使用international,因此相应的配置文件的前缀应该为international。
关于该项配置的避坑指南:例如这里仅设置为international,则国际化相应的配置文件必须在src/main/resources目录下(注意:不能再该目录的子目录下)。但如果你想把国际化的相关配置文件放在resources目录下的某个子目录下,例如放在如下子目录:
则需要修改上面的basename的配置为:
# 国际化文件基础名称
spring.messages.basename=properties/international
也就是basename配置的其实为国际化配置文件所在的目录和文件名前缀。如果上述设置出错,则会产生如下的错误提示:
springboot org.springframework.context.NoSuchMessageException: No message found under code 'msg' for locale 'zh_CN'.
正确完成以上配置文件basename的设置后,开始配置如下的三个国际化配置文件:
# properties/international.properties
# 中文:Spring MVC国际化
msg=Spring MVC\u56fd\u9645\u5316
properties/international_en_US.properties
# 英文Spring MVC internationalization
msg=Spring MVC internationalization
properties/international_zh_CN.properties
# 中文:Spring MVC国际化
msg=Spring MVC\u56fd\u9645\u5316
这样,Spring MVC就会读入这些配置的国际化信息。
2. 创建国际化解析器
这里使用Spring MVC 提供的LocaleChangeInterceptor拦截器,它可以在处理器前执行相关的逻辑,也就是拦截器的preHandle方法的作用。这个拦截器可以设置一个拦截的国际化参数,通过这个参数确定需要使用的国际化区域和相关信息,并将国际化信息保持到session中。该拦截器的实现如下:
@Configuration
public class MyWebMvcConfiguration implements WebMvcConfigurer {
/**
* 国际化参数拦截器
*/
private LocaleChangeInterceptor localeChangeInterceptor;
/**
* 注册自定义拦截器方法
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册国际化参数拦截器
// 这里将通过国家化拦截器的preHandle方法对请求的国际化区域参数进行修改
registry.addInterceptor(localeChangeInterceptor());
}
/**
* 国际化解析器BEAN,注意这个Bean的名称必须为localeResolver
*/
@Bean(name = "localeResolver")
public LocaleResolver initLocaleResolver() {
SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
// 设置默认的国际化区域
sessionLocaleResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
return sessionLocaleResolver;
}
/**
* 给处理器添加国际化参数拦截器
* 拦截的参数名称为:language
*/
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
if (localeChangeInterceptor != null) {
return localeChangeInterceptor;
}
localeChangeInterceptor = new LocaleChangeInterceptor();
// 设置拦截的参数名
localeChangeInterceptor.setParamName("language");
return localeChangeInterceptor;
}
}
3. 实现国际化控制器和视图页面
上述过程已经完成了国际化的内容,下面创建一个controller来进行测试:
@Controller
@RequestMapping("/international")
public class InternationalController {
/**
* 注入国际化消息接口对象
*/
@Autowired
private MessageSource messageSource;
/**
* 获取国际化信息和打开国际化视图
*/
@RequestMapping("/page")
public String page(HttpServletRequest request) {
// 后台获取国际化区域
Locale locale = LocaleContextHolder.getLocale();
// 获取国际化配置文件中设置的国际化消息,使用msg标志进行寻找
String msg = messageSource.getMessage("msg", null, locale);
System.out.println("msg=" + msg);
// 返回国际化视图
return "international";
}
}
相应的国际化视图页面使用JSP实现,如下:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="mvc" uri="http://www.springframework.org/tags/form" %>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%--
Created by IntelliJ IDEA.
User: yitian
Date: 2020-01-29
Time: 20:40
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Spring MVC international</title>
<link rel="stylesheet" type="text/css" href="/static/jquery-easyui-1.7.0/themes/default/easyui.css">
<link rel="stylesheet" type="text/css" href="/static/jquery-easyui-1.7.0/themes/icon.css">
<script type="text/javascript" src="/static/jquery-easyui-1.7.0/jquery.min.js"></script>
<script type="text/javascript" src="/static/jquery-easyui-1.7.0/jquery.easyui.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.0.js"></script>
<script type="text/javascript">
</script>
</head>
<body>
通过HTTP请求改变国际化:<br>
<a href="./page?language=zh_CN">简体中文</a>
<a href="./page?language=en_US">美国英文</a>
<h2><spring:message code="msg" /></h2> <br>
当前的国际化区域Locale为: ${pageContext.response.locale}
<div><a href="http://localhost:8080/web/index">返回首页</a></div>
</body>
</html>
运行项目,得到的international.jsp页面如下:(左侧页面为默认的中文页面,或者点击“简体中文”链接,右侧页面为点击“美国英文”得到的国际化页面)。
根据上图可以看到,视图的国际化已经可以通过language参数进行切换,但需要注意的是,此时国际化参数已经保存到session中,所以即使没有这个参数,也会从session中读取该参数设置国际化区域,而当3600秒后session才会失效。