SpringMVC之國際化
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.propertiesloginForm.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