SpringMVC之国际化

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 = 密码错误
本篇旨在找合适的方案来达到国际化的效果,方案有: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

猜你喜欢

转载自blog.csdn.net/u013142248/article/details/72839508