本示例已升級到Spring Boot 2.x
源碼地址:https://github.com/smltq/spring-boot-demo/tree/master/template-thymeleaf
國際化介紹
web開發中,國際化是需要考慮的一個問題,而且這個問題一般是越早敲定越好(不然等到系統大了,翻譯是個問題).下面是結合實際項目(Spring MVC+Velocity)對實現國際化的一些總結.github地址
Spring國際化
I18N:作為"國際化"的簡稱,其來源是英文單詞internationalization的首末字符i和n,18為中間的字符數.
Spring做國際化的配置主要有3個關鍵點:
- ResourceBundleMessageSource:實現國際化資源的定義.
- LocaleResolver:實現本地化信息的解析.
- LocaleChangeInterceptor:實現本地化信息的監聽(來實現url參數動態指定locale).
LocaleResolver
LocaleResolver是指用什么策略來檢測請求是哪一種locale,Spring MVC提供了一下幾種策略:
AcceptHeaderLocaleResolver
根據瀏覽器Http Header中的accept-language域判定瀏覽器的語言環境,可以通過HttpServletRequest.getLocale獲得域的內容,但是無法調用LocaleResolver接口的setLocale設置locale.基於這個策略,在后面的demo中可以實現基於瀏覽器的國際化案例.
SessionLocaleResolver
根據用戶本次會話過程中的語言設定決定語言種類,session級別的,在此session周期內可以修改語言種類,但是session失效后,語言設定失效.基於這個策略,在后面的demo中可以實現基於session的國際化案例.
CookiedLocaleResolver
根據Cookie判定用於的語言設定(Cookie中保存着用戶前一次的語言設定參數).
FixedLocaleResolver
一直使用固定的Locale,改變locale是不支持的.
如果需要使用哪一種策略,只需要在DispatcherServlet制定的Spring配置文件中配置就行,DispatchServlet將在初始化的時候調用initLocaleResolver(context)方法去配置文件中找名字為localeResolver的bean,如果有就使用配置文件的,沒有就使用默認的AcceptHeaderLocaleResovler
通過上面,了解了Spring實現國際化的相關概念,下面結合demo實例,看看Spring MVC是如何實現國際化的
- 配置文件
<!--國際化配置 start-->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:i18n/messages"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"/>
</bean>
<!--語言選擇-->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
<!--國際化配置 end-->
- demo里准備兩份語言文件分別是messages_cn.properties和messages_en.properties,內容分別如下:
Hello=Hello
HelloWorld=Hello World
SpringMvcBootstrap=Spring MVC Bootstrap
Greetings=I deeply greet you!
Hello=你好,現在是中文版
HelloWorld=你好,現在是中文版
SpringMvcBootstrap=中文版頭部
Greetings=中文版歡迎你
- 前端界面通過使用spring針對不同view視圖提供的標記處理國際化信息.velocity標記,比如demo中的hello.vm文件
#define($content)
#springMessage("Hello")
#end
-
最后運行結果會根據defaultLocale的配置顯示英語版本或中文版本,顯示效果如下:
-
以上配置示例是基於Cookie的國際化實現,國際化根據實際需求,實現方式有很多比如:
- 基於瀏覽器請求的國際化
- 基於Session的國際化實現
- 基於ULR請求的國際化實現
Velocity簡單使用
- pom.xml增加Velocity 依賴
<!-- Velocity 依賴 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-tools</artifactId>
<version>2.0</version>
</dependency>
- xml增加模板引擎配置
<!--模板引擎配置 start-->
<bean id="velocityConfig"
class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="configLocation">
<value>/WEB-INF/velocity/velocity.properties</value>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
<property name="cache" value="false"/>
<property name="layoutUrl" value="/layout/main.vm"/>
<property name="prefix" value="/templates/"/>
<property name="suffix" value=".vm"/>
<property name="exposeSpringMacroHelpers" value="true"/>
<property name="contentType" value="text/html;charset=UTF-8"/>
<property name="viewClass" value="org.springframework.web.servlet.view.velocity.VelocityLayoutView"/>
</bean>
<!--模板引擎配置 end-->
- controller代碼,hello方法會顯示hello.vm內容,helloWorld方法顯示hello-world.vm內容,入口是main.vm
@Controller
public class HelloWorldController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() {
return "hello";
}
@RequestMapping(value = "/hello-world", method = RequestMethod.GET)
public String helloWorld() {
return "hello-world";
}
@RequestMapping(value = "/hello-redirect", method = RequestMethod.GET)
public String helloRedirect() {
return "redirect:/hello-world";
}
}
- 我們看看main.vm代碼
<!doctype html>
<html>
<head>
<title>$!page_title</title>
<link href="#springUrl('/resources/css/reset.css')" rel="stylesheet" type="text/css"/>
<link href="#springUrl('/resources/css/style.css')" rel="stylesheet" type="text/css"/>
</head>
<body>
<article>
<header>#parse('/layout/header.vm')</header>
<section>$!content</section>
<footer>#parse('/layout/footer.vm')</footer>
</article>
</body>
</html>
SpringMVC和REST服務API的基本用法示例
- pom.xml增加json和xml依賴
<!-- JSON 轉換器 -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.5.3</version>
</dependency>
<!-- XML 轉換器 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.0</version>
</dependency>
- controller代碼
@Controller
public class UserServiceController {
@RequestMapping(value = "/user/{name}/{surname}.json", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody
User getUserJson(@PathVariable String name, @PathVariable String surname) {
User user = new User(name, surname);
return user;
}
@RequestMapping(value = "/user/{name}/{surname}.xml", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
public @ResponseBody
User getUserXml(@PathVariable String name, @PathVariable String surname) {
User user = new User(name, surname);
return user;
}
}
@XmlRootElement(name = "user")
public class User {
private String name;
private String surname;
public User() {
}
public User(String name, String surname) {
super();
this.name = name;
this.surname = surname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
}
- json數據結果
瀏覽器輸入http://localhost:9080/testweb/user/tq/lin.json,結果顯示如下:
{
name: "tq",
surname: "lin"
}
- xml數據結果
瀏覽器輸入http://localhost:9080/testweb/user/tq/lin.xml,結果顯示如下:
<user>
<name>tq</name>
<surname>lin</surname>
</user>