Spring MVC国际化三种方案
对开发者来说是国际化,对使用者来说是本地化。
SpringMVC 的国际化是建立在Java国际化的基础之上,也是通过提供不同国家/语言环境的消息资源,然后通过ResourceBundle
加载指定Local
对应的资源文件,再取得该资源文件中指定key
对应的消息。
国际化相关知识
Spring MVC 国际化步骤:
- 给系统加载国际化资源文件。
- 输出国际化。
Spring MVC 国际化消息有两种方式:
- 视图页面上输出国际化信息,需要使用
SpringMVC
的标签库。 - 在
Controller
的处理方法中输出国际化信息,需要使用org.springframework.web.servlet.support.RequestContext
的getMessage()
方法来完成。
国际化的通用做法是通过读取用户浏览器请求头中Accept-Language
属性值,该属性提供了关于用户浏览器的信息,根据该信息为用户选择语言区域;还可以根据HttpSession
或者Cookie
为用户选择语言区域。
Spring MVC 提供了一个语言区域解析接口LocalResolver
,该接口的常用实现类都在org.springframework.web.servlet.i18n
包下面,包括:
- AcceptHeaderLocaleResolver
- SessionLocaleResolver
- CookieLocaleResolver
基于浏览器请求的国际化实现
基于浏览器请求的国际化即根据浏览器请求的消息头中的Accept-Language
属性来选择区域性语言,默认装配 AcceptHeaderLocaleResolver
来处理来解析语言区区域。
AcceptHeaderLocaleResolver
是默认的,是最容易使用的语言解析器,会读取浏览器的Accept-Language
属性来确定使用哪个区域语言。该解析器不用显式配置。而session
和cookie
需要手动显示配置。
示例代码
通过一个登录页面来演示Spring MVC 的国际化。
- 构建前端登录页面
loginForm.jsp
,引入spring
标签库。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>基于浏览器的国际化</title>
</head>
<body>
<h3><spring:message code = "title" /></h3>
<form:form action="/springmvc_01_2/user/login" method="post" modelAttribute="user">
<table>
<tr>
<td><spring:message code="loginname" /></td>
<td><form:input path="loginname" /></td>
</tr>
<tr>
<td><spring:message code="password" /></td>
<td><form:input path="password" /></td>
</tr>
<tr>
<td><input type="submit" value="<spring:message code="submit" />" /></td>
</tr>
</table>
</form:form>
</body>
</html> - 构建登录成功后的返回页面
success.jsp
。1
2
3
4
5
6
7
8
9
10
11
12
13<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录成功</title>
</head>
<body>
<spring:message code="welcome" arguments="${requestScope.user.username}" />
</body>
</html> - 创建两个语言资源文件,
properties
文件,UTF-8
编码; 此两个文件放到项目资源目录(config
)里。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15//文件名:message_en_US.properties
loginname = Login name:
password = Password:
submit = Submit
welcome = Welcome {0} access this website
title = Login Page
username = admin
//文件名:message_zh_CN.properties
loginname = 登录名:
password = 密码:
submit = 提交
welcome = 欢迎 {0} 访问本站
title = 登录页面
username = 管理员 springmvc.xml
配置文件添加bean
,告诉那些是语言资源文件。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<!-- 国际化 :
根据value查找以该值开头的.properties资源文件
资源文件名构造:value值_请求语言.properties
-->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<!-- 国际化资源文件名, 要以配置多个值 -->
<property name="basenames">
<list>
<value>message</value>
<!-- <value>language</value> -->
</list>
</property>
<!-- 支持UTF-8的中文 -->
<property name="cacheSeconds" value="0"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<!-- 拦截器配置 -->
<mvc:interceptors>
<!-- 国际化操作拦截器 -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors>- 后端添加
User
实体类。1
2
3
4
5
6
7
8public class User {
private String username;
private String loginname;
private String password;
--- set/get方法---
} - 后端
Controller
层添加处理方法。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class LoginController {
public String loginView(Model model) {
User user = new User();
model.addAttribute("user", user);
return "loginForm";
}
public String login( User user, HttpServletRequest request, Model model){
String loginName = user.getLoginname();
String password = user.getPassword();
if (loginName != null && loginName.equals("root")
&& password != null && password.equals("root123")) {
RequestContext requestContext = new RequestContext(request);
String username = requestContext.getMessage("username");
user.setUsername(username);
model.addAttribute("user", user);
return "success";
}else {
return "error";
}
}
} - 验证国际化结果。
切换浏览器的语言顺序,发送请求。
基于Session的国际化实现
显式配置SessionLocaleResolver
语言解析器,会替换掉默认的AcceptHeaderLocaleResolver
解析器。SpringMVC会从HttpSession
域中获取用户所设置的语言来确定使用那个语言区域。
示例代码
前端添加用户可选择语言。
两个超级链接,分别用于切换中文和英文语言环境,超级连接带参数request_local
,传递语言类型。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>基于浏览器的国际化</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/user/loginV?request_local=zh_CN">中文</a> | <a href="${pageContext.request.contextPath}/user/loginV?request_local=en_US">English</a>
<h3><spring:message code = "title" /></h3>
<form:form action="/springmvc_01_2/user/login" method="post" modelAttribute="user">
<table>
<tr>
<td><spring:message code="loginname" /></td>
<td><form:input path="loginname" /></td>
</tr>
<tr>
<td><spring:message code="password" /></td>
<td><form:input path="password" /></td>
</tr>
<tr>
<td><input type="submit" value="<spring:message code="submit" />" /></td>
</tr>
</table>
</form:form>
</body>
</html>构建登录成功后的返回页面
success.jsp
。
同上:示例代码-2添加区域语言资源文件
同上: 示例代码-3在文件
springmvc.xml
里显式配置SessionLocaleResolver
。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<!-- 显式配置SessionLocaleResolver语言解析器, 替换掉默认的localResolver -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>
<!-- 国际化 :
根据value查找以该值开头的.properties资源文件
资源文件名构造:value值_请求语言.properties
-->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<!-- 国际化资源文件名, 要以配置多个值 -->
<property name="basenames">
<list>
<value>message</value>
<!-- <value>language</value> -->
</list>
</property>
<!-- 支持UTF-8的中文 -->
<property name="cacheSeconds" value="0"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<mvc:interceptors>
<!-- 国际化操作拦截器 -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors>添加实体类
同上:示例代码-5后端代码识别用户选择的语言
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class LoginController {
public String loginView(Model model, String request_local, HttpServletRequest request) {
if (request_local != null) {
if (request_local.equals("zh_CN")) {
//中文环境
Locale locale = new Locale("zh", "CN");
request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale);
} else if (request_local.equals("en_US")) {
//英文环境
Locale locale = new Locale("en", "US");
request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale);
} else {
//默认环境
request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME,
LocaleContextHolder.getLocale());
}
}
User user = new User();
model.addAttribute("user", user);
return "loginForm";
}
public String login( User user, HttpServletRequest request, Model model){
String loginName = user.getLoginname();
String password = user.getPassword();
if (loginName != null && loginName.equals("admin") && password != null && password.equals("123")) {
RequestContext requestContext = new RequestContext(request);
String username = requestContext.getMessage("username");
user.setUsername(username);
model.addAttribute("user", user);
return "success";
} else {
return "error";
}
}
}验证
单击超级链接,传递request_locale
参数,后台根据该参数进行语言环境切换。
基于Cookie的国际化实现
显式配置CookieLocaleResolver
语言区域解析器,后台根据所选择的语言参数响应对应的语言环境。
示例代码
- 前端登录页面、成功页面、区域语言资源文件、实体类java文件同上。
- 在文件
springmvc.xml
里显式配置CookieLocaleResolver
。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27<!-- 显式配置SessionLocaleResolver语言解析器, 替换掉默认的localResolver -->
<!-- <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean> -->
<!-- 显式配置CookieLocaleResolver语言解析器, 替换掉默认的localResolver -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"></bean>
<!-- 国际化 :
根据value查找以该值开头的.properties资源文件
资源文件名构造:value值_请求语言.properties
-->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<!-- 国际化资源文件名, 要以配置多个值 -->
<property name="basenames">
<list>
<value>message</value>
<!-- <value>language</value> -->
</list>
</property>
<!-- 支持UTF-8的中文 -->
<property name="cacheSeconds" value="0"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<mvc:interceptors>
<!-- 国际化操作拦截器 -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors> - 后端代码识别用户选择的语言
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class LoginController {
public String loginView(Model model, String request_local,
HttpServletRequest request,
HttpServletResponse response) {
if (request_local != null) {
if (request_local.equals("zh_CN")) {
//中文环境
Locale locale = new Locale("zh", "CN");
(new CookieLocaleResolver()).setLocale(request, response, locale);
} else if (request_local.equals("en_US")) {
//英文环境
Locale locale = new Locale("en", "US");
(new CookieLocaleResolver()).setLocale(request, response, locale);
} else {
//默认环境
(new CookieLocaleResolver()).setLocale(request, response, LocaleContextHolder.getLocale());
}
}
User user = new User();
model.addAttribute("user", user);
return "loginForm";
}
public String login( User user, HttpServletRequest request, Model model){
String loginName = user.getLoginname();
String password = user.getPassword();
if (loginName != null && loginName.equals("admin") && password != null && password.equals("123")) {
RequestContext requestContext = new RequestContext(request);
String username = requestContext.getMessage("username");
user.setUsername(username);
model.addAttribute("user", user);
return "success";
} else {
return "error";
}
}
} - 验证语言切换
点击超级链接切换语言环境,查看请求头和响应头中的Language
参数值。
Spring MVC国际化三种方案
http://blog.gxitsky.com/2018/02/10/SpringMVC-15-localResolver/