SpringMVC的国际化的具体实现方式有:1.浏览器语言环境;2..session;3.cookies;4.URL;
1.浏览器语言切换语言
springmvc配置文件
<!-- 国际化资源文件 -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="fileEncodings" value="utf-8"/>
<property name="cacheSeconds" value="120"/>
<property name="useCodeAsDefaultMessage" value="false" />
<!-- <property name="basename" value="/WEB-INF/i18n/sys/message" /> -->
<property name="basenames">
<list>
<value>/WEB-INF/i18n/sys/message</value>
<value>/WEB-INF/i18n/common/message</value>
</list>
</property>
</bean>
basename和basenames的区别为配置文件分单个文件和多个文件,basenames读取的文件分别为/WEB-INF/i18n/sys和/WEB-INF/i18n/common目录下的message前缀文件;简体中文为message_zh_CN.properties何message_en_US.properties支持更多的语言则根据不同语言代号添加相应文件,语言代号参考:https://blog.csdn.net/qq_35544379/article/details/78204811
有了上面配置切换浏览器语言即可(亲测Chrome、Firefox和IE均支持)
在页面添加spring标签,如下引用即可
效果如下:
如果切换语言发现无法改变语言,试着清掉缓存。
2.Locale放在session
springmvc配置文件的国际化资源文件messageSource仍要配置,session方式要加如下配置
<mvc:interceptors>
<!-- 国际化操作拦截器如果采用基于(请求/Session/Cookie)则必需配置 -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />
设置session的Locale,这里方便测试则通过请求参数设置Locale
@RequestMapping("/home")
public String index(HttpServletRequest request, @RequestParam(value="langType", defaultValue="zh") String langType) {
Locale locale = null;
if(langType.equals("zh")){
locale = new Locale("zh", "CN");
}else if(langType.equals("en")){
locale = new Locale("en", "US");
}else{
locale = LocaleContextHolder.getLocale();
}
request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale);
return "home";
}
登陆页面为英文
首页按参数设置为默认的zh_CN语言
切换语言en_US
不论session设置为何种语言,退出系统,清空session,仍然显示为浏览器语言设置的en_US
3.Locale放在cookie
session和cookie的区别是session的localeResolver为SessionLocaleResolver,cookie的为CookieLocaleResolver;
<mvc:interceptors>
<!-- 国际化操作拦截器如果采用基于(请求/Session/Cookie)则必需配置 -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" />
cookie设置
@RequestMapping("/home")
public String index(HttpServletRequest request, HttpServletResponse response) {
(new CookieLocaleResolver()).setLocale (request, response, new Locale("zh", "CN"));
return "home";
}
浏览器语言仍是en_US
进入首页,cookie设置Locale为zh_CN
退出登录仍会显示为zh_CN
清空cookie方可切换为浏览器语言对应的Locale;(tip:浏览器清楚内容的快捷键Ctrl+Shift+Delete);
4.URL传递Locale参数
springmvc配置文件,参考session和cookie方式,将localeResolver换成本地自定义的com.chensan.common.interceptor.MyAcceptHeaderLocaleResolver;MyAcceptHeaderLocaleResolver文件内容如下:
package com.chensan.common.interceptor;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
public class MyAcceptHeaderLocaleResolver extends AcceptHeaderLocaleResolver {
private Locale myLocal;
public Locale resolveLocale(HttpServletRequest request) {
return myLocal;
}
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
myLocal = locale;
}
}
Controller不再设置Locale
@RequestMapping("/home")
public String index() {
return "home";
}
在每次URL访问时添加参数locale=en_US或locale=zh_CN切换语言
注意:在session方式那里自定义的langType参数只是给SessionLocaleResolver赋值(只是为了方便测试,不要误解),并不是URL方式直接设置Locale的值。
无意中发现的,在使用SessionLocaleResolver时在url添加locale=zh_CN或者locale=en_US则可切换语言。刚开始感觉奇怪,但细想想这跟URL方式是一样大的,只是在URL方式的时候自定义的MyAcceptHeaderLocaleResolver继承自AcceptHeaderLocaleResolver,也就不感到奇怪了。即只须配置localeResolver,不论SessionLocaleResolver、CookieLocaleResolver还是自定义的localeResolver,就可以用URL加参数locale=zh_CN或者locale=en_US的方式切换语言。
=============================下面内容为后台验证的内容,后续会单独写一篇
springMVC配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 开启springmvc注解 -->
<mvc:annotation-driven validator="validator" conversion-service="conversion-service"/>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
<!--不设置则默认为classpath下的 validationMessages_zh_CN.properties -->
<property name="validationMessageSource" ref="messageSource"/>
</bean>
<bean id="conversion-service" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="fileEncodings" value="utf-8"/>
<property name="cacheSeconds" value="120"/>
<property name="useCodeAsDefaultMessage" value="false" />
<!-- 配置单个国际化文件 -->
<!--
<property name="basename" value="/WEB-INF/static/i18n/validateMessages"/>
-->
<!-- 配置多个国际化文件 -->
<property name="basenames">
<list>
<value>/WEB-INF/i18n/sys/sys</value>
</list>
</property>
</bean>
<!-- 自动扫描包 -->
<context:component-scan base-package="com.chensan"/>
<!-- springmvc不过滤的目录和文件 -->
<mvc:resources mapping="/public/**" location="/WEB-INF/public/" />
<!-- 配置视图解析器:如何把Handler方法返回值解析为实际的物理视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
其实在
SpringMVCJSR-303规范进行校验简单示例已实现了国际化效果,只是本篇需要讨论的是如果动态选择、切换语言版本;
LoginModel(这里只列出两个@valid的属性)
/**
* 用户名.
*/
@Length(min = 4, max = 50, message="{loginForm.userName.length}")
private String userName;
/**
* 密码.
*/
@Length(min = 6, max = 20, message = "{loginForm.password.length}")
private String password;
Controller里的注解
@RequestMapping(value="/signIn", method=RequestMethod.POST)
public String signIn(@Valid @ModelAttribute("formModel") LoginModel formModel, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return Login_View_Name;
}
UserMedic user = currentUserService.getUser(formModel.getUserName());
if (user == null) {
bindingResult.rejectValue("userName", "userName.not.exist");
return Login_View_Name;
}
String pwd = MDCipher.MD5HexString(formModel.getPassword());
if (!user.getLoginPwd().equals(pwd)) {
bindingResult.rejectValue("password", "password.error");
return Login_View_Name;
}
HttpSession session = request.getSession();
session.setAttribute("loginname", user.getLoginName());//将用户存到session
return String.format("redirect:/%s", "home");
}
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="sm"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf"%>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="public/img/favicon.png">
<title>登录页</title>
</head>
<body>
<sf:form modelAttribute="formModel"
action="${pageContext.request.contextPath}/signIn" method="post" role="form">
<label for="userName">
<sm:message code="loginForm.userName"/>
</label>
<input type="text" name="userName" id="userName"
placeholder="<sm:message code="loginForm.userName"/>" autofocus>
<sf:errors path="userName" cssClass="errorMsg"/>
<label for="password">
<sm:message code="loginForm.password"/>
</label>
<input type="password" name="password" id="password"
placeholder="<sm:message code="loginForm.password"/>">
<sf:errors path="password" cssClass="errorMsg"/>
</sf:form>
</body>
</html>
该jsp省略了样式提交按钮等等内容,只保留国际化了的部分内容,方便直观看到如何进行设置的;
其中spring的form标签中的modelAttribute属性值对应的Controller中signIn方法的@modelAttribute,用于表单验证;
spring的errors标签用于输出表单验证错误信息;
spring的message标签用于输出内容;
国际化文件在WEB-INF/static/i18n文件夹下validateMessages_en_US.properties
loginForm.userName = userName
loginForm.password = password
loginForm.userName.length = userName length is {min} to {max} char
loginForm.password.length = password length is {min} to {max} char
userName.not.exist = userName is not exists
password.error = password is error
validateMessages_zh_CN.properties
loginForm.userName = 登录名
loginForm.password = 密码
loginForm.userName.length = 用户名长度在 {min} 至 {max} 个字符之间
loginForm.password.length = 密码长度为 {min} 到 {max} 位
userName.not.exist = 用户不存在
password.error = 密码错误
参考:http://www.cnblogs.com/liukemng/p/3750117.html