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.LocaleContextHolderlocale 专门的支持,通过 ThreadLocal 实现的上下文绑定,能直接获取 locale 等信息
