文章目录
- 一、SpringMVC国际化的步骤
- 1.国际化文件
- 2.SpringMVC管理国际化资源文件
- 3.在页面取值
- 二、国际化区域信息解析器
- 三、在程序中获取国际化信息
- 四、扩展:点击链接切换国际化
- 方式1:自定义区域信息解析器
- 方式2:使用SessionLocaleResolver实现国际化
- 方式3:SessionLocaleResolver配合LocaleChangeInterceptor完成点击链接国际化
使用SpringMVC来做国际化只有三步:
①写好国际化文件。
②让SpringMVC的ResourceBundleMessageSource管理国际化资源文件。
③直接去页面取值。
一、SpringMVC国际化的步骤
1.国际化文件
仅以中英国际化为例,国际化文件的文件名如下:
- i18n_zh_CN.properties 中文(简体)
- i18n_en_US.properties 英语(美国)
- i18n_en.properties 中文
- i18n_zh.properties 英文
创建哪种文件可以根据上图中浏览器的的语言环境。
2.SpringMVC管理国际化资源文件
- 在SpringMVC中配置
ResourceBundleMessageSource
。 - value=“loginpage/i18n”:表示配置文件为loginpage文件夹下的i18n。
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="loginpage/i18n"></property>
</bean>
3.在页面取值
- 在显示页面使用
fmt
进行取值。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>
<fmt:message key="welcomeinfo"/>
</h1>
<form action="">
<fmt:message key="username"/>:<input/><br/>
<fmt:message key="password"/>:<input/><br/>
<input type="submit" value="<fmt:message key="loginBtn"/>">
</form>
</body>
</html>
二、国际化区域信息解析器
private LocaleResolver localeResolver;
:SpringMVC中的区域信息是由这个区域信息解析器得到的,该解析器是SpringMVC九大组件之一。
所有用到区域信息的地方,都是用LocaleResolver默认装配的AcceptHeaderLocaleResolver
来获取 。
(1) AcceptHeaderLocaleResolver:使用请求头的区域信息
源码:
public class AcceptHeaderLocaleResolver implements LocaleResolver {
...
@Override
public Locale resolveLocale(HttpServletRequest request) {
return request.getLocale();
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
throw new UnsupportedOperationException(
"Cannot change HTTP accept header - use a different locale resolution strategy");
}
...
}
(2) FixedLocaleResolver:使用系统默认的区域信息
源码:
public class FixedLocaleResolver extends AbstractLocaleContextResolver {
...
@Override
public Locale resolveLocale(HttpServletRequest request) {
Locale locale = getDefaultLocale();
if (locale == null) {
locale = Locale.getDefault();
}
return locale;
}
@Override
public LocaleContext resolveLocaleContext(HttpServletRequest request) {
return new TimeZoneAwareLocaleContext() {
@Override
public Locale getLocale() {
return getDefaultLocale();
}
@Override
public TimeZone getTimeZone() {
return getDefaultTimeZone();
}
};
}
@Override
public void setLocaleContext(HttpServletRequest request, HttpServletResponse response, LocaleContext localeContext) {
throw new UnsupportedOperationException("Cannot change fixed locale - use a different locale resolution strategy");
}
...
}
(3) SessionLocaleResolver:区域信息是从Session中获取
源码:
public class SessionLocaleResolver extends AbstractLocaleContextResolver {
...
@Override
public Locale resolveLocale(HttpServletRequest request) {
Locale locale = (Locale) WebUtils.getSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME);
if (locale == null) {
locale = determineDefaultLocale(request);
}
return locale;
}
...
}
(4)CookieLocaleResolver:区域信息是从Cookie中获取
public class CookieLocaleResolver extends CookieGenerator implements LocaleContextResolver {
...
@Override
public Locale resolveLocale(HttpServletRequest request) {
parseLocaleCookieIfNecessary(request);
return (Locale) request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME);
}
...
}
三、在程序中获取国际化信息
- 这样有什么用呢?之前在做JSR303校验时,如果不使用表单标签,而使用原生表单,可以增加Model参数,可以把国际化信息拿到后放入隐含模型中,再到页面中取出。
@Autowired
private ResourceBundleMessageSource messageSource;
@RequestMapping("/tologinPage")
public String tologinpage(Locale locale) {
System.out.println(locale);
String message = messageSource.getMessage("welcomeinfo", null, locale);
System.out.println(message);
return "login";
}
四、扩展:点击链接切换国际化
方式1:自定义区域信息解析器
处理器页面
@Autowired
private ResourceBundleMessageSource messageSource;
@RequestMapping("/tologinPage")
public String tologinpage(Locale locale) {
System.out.println(locale);
String message = messageSource.getMessage("welcomeinfo", null, locale);
System.out.println(message);
return "login";
}
自定义区域信息解析器
public class MyLocaleResolver implements LocaleResolver {
// 解析区域信息
@Override
public Locale resolveLocale(HttpServletRequest req) {
Locale l = null;
String localeStr = req.getParameter("locale");
// 如果带了locale参数,就用参数指定的信息,没带就用请求头的
if (localeStr != null && !"".equals(localeStr)) {
// 将字符串切分
l = new Locale(localeStr.split("_")[0], localeStr.split("_")[1]);
} else {
l = req.getLocale();
}
return l;
}
// 设置区域信息
@Override
public void setLocale(HttpServletRequest arg0, HttpServletResponse arg1, Locale arg2) {
// 该异常模仿AcceptHeaderLocaleResolver
throw new UnsupportedOperationException(
"Cannot change HTTP accept header - use a different locale resolution strategy");
}
}
显示页面
<body>
<h1>
<fmt:message key="welcomeinfo"/>
</h1>
<form action="">
<fmt:message key="username"/>:<input/><br/>
<fmt:message key="password"/>:<input/><br/>
<input type="submit" value="<fmt:message key="loginBtn"/>">
</form>
<a href="tologinPage?locale=zh_CN">中文</a>|<a href="tologinPage?locale=en_US">English</a>
</body>
显示页面如下,点击中/英文连接可以切换语言:
方式2:使用SessionLocaleResolver实现国际化
- 从请求参数中获得locale的值,如果没带就用中文。即拿到代表区域信息的参数字符串后,包装成一个Locale对象,放入Session中。
@Autowired
private ResourceBundleMessageSource messageSource;
@RequestMapping("/tologinPage")
public String tologinpage(@RequestParam(value = "locale", defaultValue = "zh_CN") String localeStr, Locale locale,
HttpSession session) {
System.out.println(locale);
String message = messageSource.getMessage("welcomeinfo", null, locale);
System.out.println(message);
Locale l = null;
// 如果带了locale参数,就用参数指定的信息,没带就用默认的
if (localeStr != null && !"".equals(localeStr)) {
// 将字符串切分
l = new Locale(localeStr.split("_")[0], localeStr.split("_")[1]);
} else {
l = locale;
}
session.setAttribute(SessionLocaleResolver.class.getName() + ".LOCALE", l);
return "login";
}
配置Session区域信息解析器
- 区域信息从Session中拿
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>
依然可以完成中英文切换
方式3:SessionLocaleResolver配合LocaleChangeInterceptor完成点击链接国际化
- SpringMVC中配置LocaleChangeInterceptor和localeResolver。
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors>
处理器
- 将处理器信息请求参数包装成Locale的事情交给LocaleChangeInterceptor去做。
@Autowired
private ResourceBundleMessageSource messageSource;
@RequestMapping("/tologinPage")
public String tologinpage(String localeStr, Locale locale,
Model model, HttpSession session) {
System.out.println(locale);
String message = messageSource.getMessage("welcomeinfo", null, locale);
System.out.println(message);
return "login";
}
##SessionLocaleResolver&LocaleChangeInterceptor的工作原理
LocaleChangeInterceptor拦截器
帮我们完成的步骤:
①发请求时带了一个区域信息参数叫做locale,其中指定了新的区域信息。
②获得locale参数信息,将其解析为Locale对象.
③将Locale对象放入LocaleResolver中。
LocaleChangeInterceptor还帮我们把区域信息Locale设置为Session的属性(装入Session中)。
来到页面后,可以使用SessionLocaleResolver区域信息解析器
获取区域信息(从Session中获取)。