一、本地化
spring框架的大部分都支持国际化,就像springMVC一样。DispatcherServlet使你能够动态的通过客户端的本地语言进行配置。这是通过LocaleResolver完成的。
当一个请求到达,DispatcherServlet就会寻找LocaleResolver,如果找到就会试图通过它进行本地化。通过RequestContext.getLocale()方法我们可以得到locale resolver解释的本地化语言。
public ModelAndView handleRequest(HttpServletRequest req,
HttpServletResponse res) throws Exception {
RequestContext requestContext = new RequestContext(req);
Locale myLocale = requestContext.getLocale();
System.out.println(myLocale);
}
Locale resolvers和拦截器定义在org.springframework.web.servlet.i18n包中,并且可以在application context中进行配置。下面是本地化解析器的配置部分。(一)AcceptHeaderLocaleResolver
这个Locale resolvers依据 accept-language请求头信息进行解析处理,通常这个头信息包含客户端操作信息的本地标示。
(二)CookieLocaleResolver
这个解析器通过cookie寻找客户端特定的语言信息。如果找到,则使用这个配置。使用这个Locale resolvers的一些属性,我们可以指定这个cookie的名称甚至是最大存活时间。下面是一个配置实例:
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="cookieName" value="clientlanguage"/>
<!-- in seconds. If set to -1, the cookie is not persisted (deleted when browser shuts down) -->
<property name="cookieMaxAge" value="100000">
</bean>
下面是CookieLocaleResolver的属性列表property default description
cookieName classname+LOCAL cookie的名称
cookieMaxAge Integer.MAX_INT 最大存活时间
cookiePath / 限制可以访问cookie的程序路径。
(三)SessionLocaleResolver
这个解析器允许你通过session解析本地设置。
(四)LocaleChangeInterceptor
通过配置LocaleChangeInterceptor,我们可以动态改变本地语言。它会检测请求中的参数并且改变地区信息。它调用LoacalResolver.setLocal()进行配置。下面的例子显示了,调用所有的*.view资源包含一个名字叫做siteLanguage的变量,来改变地区信息。所以下面的URL:http://www.sf.net/home.view?siteLanguage=nl 将会改变站点语言为荷兰语。
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="siteLanguage"/>
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor"/>
</list>
</property>
<property name="mappings">
<value>/**/*.view=someController</value>
</property>
</bean>
二、国际化
关键需要加入如下配置,指定国际化资源:
<!-- 国际化资源文件 -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="useCodeAsDefaultMessage" value="true" />
<property name="cacheSeconds" value="10"></property>
<property name="defaultEncoding" value="iso-8859-1" />
</bean>
useCodeAsDefaultMessage、cacheSeconds、defaultEncoding都是可选的。“useCodeAsDefaultMessage”,默认为false,这样当Spring在ResourceBundle中找不到messageKey的话,就抛出NoSuchMessageException, 把它设置为True,则找不到不会抛出异常,而是使用messageKey作为返回值。
ReloadableResourceBundleMessageSource加载时,默认使用DefaultResourceLoader,他会先判断资源path是否带有classpath:前缀,如果有,用 ClassPathResource去加载资源文件,如果没有试着用文件协议的url去访问,再没有就在contextPath即WEB-INF下查找。
“classpath:messages”指的是classpath路径下的messages_zh_CN.properties文件和messages_en_US.properties文件。在这个配置文件的最后配置的是一个拦截器,该拦截器通过名为”lang”的参数来拦截HTTP请求,使其重新设置页面的区域化信息。
messages_zh_CN.properties文件:
language.cn = \u4e2d\u6587
language.en = \u82f1\u6587
internationalisation = \u56fd\u9645\u5316
welcome = \u6b22\u8fce\u8bbf\u95ee\u201c\u007a\u0069\u0066\u0061\u006e\u0067\u0073\u006b\u0079\u7684\
messages_en_US.properties文件:
language.cn = Chinese
language.en = English
internationalisation = \u0020Internationalisation
welcome = Welcome to visit "zifangsky's personal blog"
注:上面一些看起来“乱码”的地方实际上是经过Unicode编码的。增加配置信息:
<!-- 存储区域设置信息 -->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />
<mvc:interceptors>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
</mvc:interceptors>
编写测试controller:
@Controller
public class I18nController {
@RequestMapping(value = "/hello")
public ModelAndView welcome() {
ModelAndView modelAndView = new ModelAndView("welcome");
return modelAndView;
}
}
这个controller很简单,就是转到一个视图页面welcome.jsp:
<% response.sendRedirect("hello.html"); %>
意思很简单,就是项目启动之后就请求htllo.html,也就是让controller中的welcome方法处理这个请求。
welcome.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="mvc" uri="http://www.springframework.org/tags/form" %>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html>
<head>
<title>SpringMVC<spring:message code="internationalisation" /></title>
</head>
<body>
Language: <a href="?lang=zh_CN"><spring:message code="language.cn" /></a> - <a href="?lang=en_US"><spring:message code="language.en" /></a>
<h2>
<spring:message code="welcome" />
</h2>
Locale: ${pageContext.response.locale }
</body>
</html>
可以看出,在需要使用国际化处理的地方都使用了Spring的message标签,code属性对应资源文件中的“键”名称。最后的显示效果如下:
中文:
英文: