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 errorvalidateMessages_zh_CN.properties
loginForm.userName = 登录名 loginForm.password = 密码 loginForm.userName.length = 用户名长度在 {min} 至 {max} 个字符之间 loginForm.password.length = 密码长度为 {min} 到 {max} 位 userName.not.exist = 用户不存在 password.error = 密码错误本篇旨在找合适的方案来达到国际化的效果,方案有:1.浏览器语言环境;2..session;3.cookies;4.URL;
效果图如下:
方案一:浏览器语言环境
Chrome、IE、Firefox等主流浏览器均可实现语言切换
Chrome高级设置/语言 添加其他语言,拖拽语言顺序
IE
Firefox
方案二:将Locale放在session中
springmvc-config.xml中添加配置
<mvc:interceptors> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" /> </mvc:interceptors> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />
Controller中的signId方法如下:
@RequestMapping(value="/signIn", method=RequestMethod.POST) public String signIn(@Valid @ModelAttribute("formModel") LoginModel formModel, BindingResult bindingResult, @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); 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 form的action添加?langType=zh
Controller中比之方案一添加了langType的判断,将Locale的添加到session中,则本session中的将用session中的locale值作为当前语言;方案三:将Locale放在cookie中
与方案二session方式的区别:
springmvc-config.xml中
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />换成
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" />
这里的cookie有三个属性,使用默认值,如果需要配置可参考:
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> <!-- 设置cookieName名称,可以根据名称通过js来修改设置,也可以像上面演示的那样修改设置,默认的名称为 类名+LOCALE(即:org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE--> <property name="cookieName" value="lang"/> <!-- 设置最大有效时间,如果是-1,则不存储,浏览器关闭后即失效,默认为Integer.MAX_INT--> <property name="cookieMaxAge" value="100000"> <!-- 设置cookie可见的地址,默认是“/”即对网站所有地址都是可见的,如果设为其它地址,则只有该地址或其后的地址才可见--> <property name="cookiePath" value="/"> </bean>
Controller如下:(只是存Locale的方式换成了cookie)
@RequestMapping(value="/signIn", method=RequestMethod.POST) public String signIn(HttpServletRequest request, HttpServletResponse response, @Valid @ModelAttribute("formModel") LoginModel formModel, BindingResult bindingResult, @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(); } (new CookieLocaleResolver()).setLocale (request, response, locale); 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"); }
方案四:URL中添加?locale=en_US或?locale=zh_CN等语言
springmvc-config.xml中的localeResolver与方案二和方案三相比换成本地的LocaleSolver
<bean id="localeResolver" class="com.chensan.interceptor.MyAcceptHeaderLocaleResolver"/>
MyAcceptHeaderLocaleResolver如下:
package com.chensan.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用session和cookie的方式都可以(参考方案二和方案三)
login.jsp form的action添加locale=en_US或者locale=zh_CN;
参考:http://www.cnblogs.com/liukemng/p/3750117.html