Spring 架构的大多数部分都支持国际化,正如 Spring Web MVC 框架一样。DispatcherServlet 让你通过使用客户端的 locale 自动解决消息。这是由LocaleResolver 对象完成的。
当一个请求进来时,DispatcherServlet 会寻找一个 locale resolver,如果它找到了,它就会尝试用它来设置 locale。通过使用RequestContext.getLocale()
方法,你总是可以检索到由 locale 解析器解析的 locale。
除了自动的 locale 解析,你还可以在处理程序映射中附加一个拦截器(关于处理程序映射拦截器的更多信息,请参见 拦截),以便在特定情况下(例如,基于请求中的一个参数)改变 locale。
定位解析器和拦截器定义在 org.springframework.web.servlet.i18n
包中,并以正常方式在你的应用程序上下文中进行配置。Spring 中包含以下 locale resolvers 解析程序选择:
- Time Zone: 时区
- Header Resolver:头解析器
- Cookie Resolver:Cookie 解析器
- Session Resolver:session 解析器
- Locale Interceptor:区域拦截器
Time Zone
除了获得客户端的 locale 之外,知道它的时区也是很有用的。LocaleContextResolver 接口提供了对 LocaleResolver 的扩展,让解析器提供一个更丰富的 LocaleContext,其中可能包括时区信息。
当可用时,用户的时区可以通过使用 RequestContext.getTimeZone()
方法获得。时区信息会被任何与 Spring 的 ConversionService 注册的日期/时间转换器和格式化器对象自动使用。
Header 解析器
这个 locale 解析器检查由客户端(例如,一个网络浏览器)发送的请求中的 accept-language
标头。通常,这个头字段包含了客户的操作系统的 locale 。请注意,这个解析器不支持时区信息。
Cookie 解析器
这个 locale 解析器检查客户端上可能存在的 Cookie,以查看是否指定了一个 Locale
或 TimeZone
。如果有,它就会使用指定的规范。通过使用这个 locale 解析器的属性,你可以指定 Cookie 的名称以及最大年龄。下面的例子定义了一个 CookieLocaleResolver:
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="cookieName" value="clientlanguage"/>
<!-- 以秒为单位。如果设置为 -1,该 cookie 不会被持续保存(在浏览器关闭时删除)。 -->
<property name="cookieMaxAge" value="100000"/>
</bean>
下表描述了 CookieLocaleResolver 支持的属性:
Property | Default | Description |
---|---|---|
cookieName | classname + LOCALE | cookie 名称 |
cookieMaxAge | Servlet 容器默认值 | 一个 cookie 在客户端持续的最长时间。如果指定为 -1,cookie 将不会被持久化。它只在客户端关闭浏览器之前可用。 |
cookiePath | / | 将 cookie 的可见性限制在您网站的某个部分。当 cookiePath 被指定时, cookie 只对该路径和它下面的路径可见。 |
Session 解析器
SessionLocaleResolver 让你从可能与用户请求相关的会话中检索 Locale 和 TimeZone。与 CookieLocaleResolver 相反,该策略将本地选择的 locale设置存储在 Servlet 容器的 HttpSession 中。因此,这些设置在每个会话中都是临时的,因此在每个会话结束时都会丢失。
请注意,这与外部会话管理机制(如 Spring Session 项目)没有直接关系。这个 SessionLocaleResolver 针对当前的 HttpServletRequest 评估并修改了相应的 HttpSession 属性。
Locale 拦截器
你可以通过将 LocaleChangeInterceptor 添加到 HandlerMapping 定义中的一个,来实现 locale 的改变。它检测请求中的一个参数,并相应地改变locale,在调度器的应用上下文中调用 LocaleResolver 的 setLocale 方法。下一个例子显示,对所有包含名为 siteLanguage 的参数的 *.view
资源的调用现在会改变 locale。因此,例如,对 URL 的请求,[https://www.sf.net/home.view?siteLanguage=nl](https://www.sf.net/home.view?siteLanguage=nl)
,将网站语言改为荷兰语。下面的例子显示了如何拦截 locale。
<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>
总结
可以通过如下工具类获取相关信息:
org.springframework.web.servlet.support.RequestContextUtils
通过给它一个 HttpServletRequest 获取 locale 等信息org.springframework.context.i18n.LocaleContextHolder
locale 专门的支持,通过 ThreadLocal 实现的上下文绑定,能直接获取 locale 等信息