最近在對一個項目進行重構,使用Spring Boot將原來的項目進行功能拆分,使得之後對於功能的裝卸能夠更加簡單快捷。
然後在國際化配置時發現和原來的項目配置有一些出入。
先來講下Spring Boot中的配置方式吧。
因爲原來項目中用的是
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
的
<spring:message code='XXX'/>
標籤實現的國際化(並且原項目前臺都是jsp頁面,所以轉成thymeleaf模板成本太大),所以這裏主要講該方式,而Spring boot的thymeleaf模板自身就實現了#{XX}
的國際化實現方式,這個網上也比較容易找到,就不說了。
首先新建一個Spring Boot項目
目錄結構
相關配置
pom.xml,相關依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- jsp支持 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
添加i18n配置文件I18nConfig和MyLocaleResolver
I18nConfig
該文件爲設置默認語言,在項目啓動時會被spring掃描後初始化。
package com.my.myI18n.config;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class I18nConfig {
private static Logger logger = LoggerFactory.getLogger(I18nConfig.class);
@Bean(name = "localeResolver")
public MyLocaleResolver myLocaleResolver(){
logger.info("#####cookieLocaleResolver---create");
MyLocaleResolver myLocaleResolver = new MyLocaleResolver();
myLocaleResolver.setDefaultLocale(Locale.CHINA);
logger.info("#####cookieLocaleResolver:");
return myLocaleResolver;
}
}
MyLocaleResolver
最核心的設置文件,可以通過setLocale
方法來修改Local值。
實際爲一個攔截器,每次加載頁面時都會被調用,及每次加載頁面時都會設置並修改語言。
package com.my.myI18n.config;
import java.util.Locale;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import org.springframework.web.servlet.support.RequestContextUtils;
public class MyLocaleResolver extends AcceptHeaderLocaleResolver {
private Locale myLocal;
@Override
public Locale resolveLocale(HttpServletRequest request) {
return myLocal==null?request.getLocale():myLocal;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
myLocal = locale;
}
}
application.properties
i18n.messages
意思爲在resources/i18n文件夾下,前綴爲messages的所有文件
server.port=8080
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
### i18n setting.
spring.messages.basename=i18n.messages
spring.messages.cache-duration=3600
spring.messages.encoding=UTF-8
#spring.messages.fallback-to-system-locale=true
server.tomcat.uri-encoding=UTF-8
spring.http.encoding.charset=UTF-8
新建messages.properties,messages_zh.properties,messages_en.properties幾個文件
我這裏如果沒有messages.properties文件的話運行時會報錯,應該是必須要有一個默認文件。
默認文件的作用是當找不到具體的語言文件時,會從默認文件中取值。
所以這裏默認文件中的內容和zh中的一樣就可以了
內容
zh&默認
commom.layout.header.logout=\u9000\u51FA
en
commom.layout.header.logout=Login Out
其他的jp什麼的根據自己項目需要國際化的語言自行添加
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<spring:message code='commom.layout.header.logout'/>
<a href="language?language=zh"> 中文 </a>
<a href="language?language=en"> english </a>
</body>
</html>
然後MyControll.java
package com.my.myI18n.controll;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.support.RequestContextUtils;
@Controller
@RequestMapping(value = "/test")
public class MyControll {
@RequestMapping(value = "/i18nTest")
public String getHome(HttpServletRequest request,HttpServletResponse response) {
return "/index";
}
@RequestMapping(value = "/language")
public String getlanguage(HttpServletRequest request,HttpServletResponse response,String language) {
Locale locale= request.getLocale();
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
language=language.toLowerCase();
if(language==null||language.equals("")){
return "/index";
}else{
if(language.equals("zh")){
localeResolver.setLocale(request, response, Locale.CHINA);
}else if(language.equals("en")){
localeResolver.setLocale(request, response, Locale.ENGLISH);
}else{
localeResolver.setLocale(request, response, Locale.CHINA );
}
}
return "/index";
}
}
現在啓動項目嘗試下
點擊english
OK,成功切換了。
使用cookie持久化
但是在需要重構的項目中,所使用的方式是用一個cookie來持久化用戶語言類型,然後使用spring mvc中的一個框架自動設置語言類型的,所以和這裏的還有些不同,需要進一步修改。
因爲cookie是持久化在客戶端的,所以這裏可以直接使用js來操作cookie,少了一步與後臺的交互,速度也會快很多。這裏模擬下項目中的實現方式。
這裏使用的cookie名爲ClientLanguage
修改index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<spring:message code='commom.layout.header.logout'/>
<!-- <a href="language?language=en"> 中文 </a> -->
<!-- <a href="language?language=zh"> english </a> -->
<a href="javascript:;" onclick="changeLang('zh')"> 中文 </a>
<a href="javascript:;" onclick="changeLang('en')"> english </a>
</body>
<script>
function changeLang(lang){
document.cookie="ClientLanguage="+lang;
location.reload();
}
</script>
</html>
刪除MyControll.java中的getlanguage
方法
因爲直接在前臺就已經將cookie的值設置好了。
然後修改MyLocaleResolver.java文件
使得每次加載時都會從cookie中獲取用戶語言類型
public Locale resolveLocale(HttpServletRequest request) {
Cookie[] cookies = request.getCookies(); //獲取cookie數組
String lang="";
for(Cookie cookie:cookies){//遍歷cookie數組
if("ClientLanguage".equals(cookie.getName())) {
lang=cookie.getValue();
break;
}
}
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
// String lang=(String)request.getSession().getAttribute("iLearnLanguage");
if(lang==null||"".equals(lang)) {
myLocal=Locale.CHINA;
}else {
if(lang.equals("zh")) {
myLocal=Locale.CHINA;
}else if(lang.equals("en")) {
myLocal=Locale.ENGLISH;
}else if(lang.equals("ja")) {
myLocal=Locale.JAPAN;
}
}
// return myLocal==null?request.getLocale():myLocal;
return myLocal;
}
然後運行,點擊修改爲英文,查看cookie
成功切換過來了。
這樣是不是更加簡單清爽了?實際上只需要添加2個文件(I18nConfig.java,MyLocaleResolver.java),然後在配置文件中添加3行配置,就可以輕鬆實現國際化。
前臺接入也只需如下幾行。
<a href="javascript:;" onclick="changeLang('zh')"> 中文 </a>
<a href="javascript:;" onclick="changeLang('en')"> english </a>
</body>
<script>
function changeLang(lang){
document.cookie="ClientLanguage="+lang;
location.reload();
}
</script>