Locale

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,以查看是否指定了一个 LocaleTimeZone。如果有,它就会使用指定的规范。通过使用这个 locale 解析器的属性,你可以指定 Cookie 的名称以及最大年龄。下面的例子定义了一个 CookieLocaleResolver:

  1. <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
  2. <property name="cookieName" value="clientlanguage"/>
  3. <!-- 以秒为单位。如果设置为 -1,该 cookie 不会被持续保存(在浏览器关闭时删除)。 -->
  4. <property name="cookieMaxAge" value="100000"/>
  5. </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。

  1. <bean id="localeChangeInterceptor"
  2. class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
  3. <property name="paramName" value="siteLanguage"/>
  4. </bean>
  5. <bean id="localeResolver"
  6. class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>
  7. <bean id="urlMapping"
  8. class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  9. <property name="interceptors">
  10. <list>
  11. <ref bean="localeChangeInterceptor"/>
  12. </list>
  13. </property>
  14. <property name="mappings">
  15. <value>/**/*.view=someController</value>
  16. </property>
  17. </bean>

总结

可以通过如下工具类获取相关信息:

  • org.springframework.web.servlet.support.RequestContextUtils 通过给它一个 HttpServletRequest 获取 locale 等信息
  • org.springframework.context.i18n.LocaleContextHolderlocale 专门的支持,通过 ThreadLocal 实现的上下文绑定,能直接获取 locale 等信息