地区设置(Locale)
Spring架构的大部分部分都支持国际化,Spring Web MVC框架也是如此。DispatcherServlet允许你使用客户端的区域设置(locale)来自动解析消息。这是通过LocaleResolver对象来实现的。
当有请求到来时,DispatcherServlet会寻找一个区域设置解析器(locale resolver),如果找到,则会尝试使用它来设置区域设置。通过使用RequestContext.getLocale()方法,你总能获取到由该区域设置解析器所解析出的区域设置。
除了自动区域设置解析外,您还可以将拦截器附加到处理器映射上(有关处理器映射拦截器的更多信息,请参见拦截),以便在特定情况下更改区域设置(例如,根据请求中的某个参数)。
Locale解析器和拦截器在org.springframework.web.servlet.i18n包中定义,并且以常规方式在应用程序上下文中进行配置。Spring中包含了以下几种Locale解析器。
时区
除了获取客户端的区域设置(locale)之外,了解其时区通常也很有用。LocaleContextResolver接口为LocaleResolver提供了一个扩展,使得解析器能够提供更丰富的LocaleContext,其中可能包含时区信息。
当可用时,可以使用RequestContext.getTimeZone()方法获取用户的TimeZone。任何注册到Spring的ConversionService中的Date/Time Converter和Formatter对象都会自动使用时区信息。
Header Resolver
此区域设置解析器会检查客户端(例如,网络浏览器)发送的请求中的accept-language头部信息。通常,该头部字段包含客户端操作系统的区域设置。请注意,此解析器不支持时区信息。
Cookie 解析器
此区域设置解析器会检查客户端上可能存在的Cookie,以查看是否指定了Locale或TimeZone。如果指定了,它将使用这些指定的详细信息。通过使用此区域设置解析器的属性,您可以指定cookie的名称以及最大有效期。以下示例定义了一个CookieLocaleResolverbean:
- Java
- Kotlin
- Xml
@Configuration
public class WebConfiguration {
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver("clientlanguage");
localeResolver.setCookieMaxAge(Duration.ofSeconds(100000));
return localeResolver;
}
}
@Configuration
class WebConfiguration {
@Bean
fun localeResolver(): LocaleResolver = CookieLocaleResolver("clientlanguage").apply {
setCookieMaxAge(Duration.ofSeconds(100000))
}
}
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<constructor-arg index="0" value="clientlanguage"/>
<!-- in seconds. If set to -1, the cookie is not persisted (deleted when browser shuts down) -->
<property name="cookieMaxAge" value="100000"/>
</bean>
Session Resolver
SessionLocaleResolver 允许你从与用户请求相关联的会话中获取 Locale 和 TimeZone。与 CookieLocaleResolver 不同,这种策略将用户本地选择的区域设置存储在 Servlet 容器的 HttpSession 中。因此,这些设置对于每个会话来说都是临时的,当每个会话结束时就会丢失。
请注意,它与外部会话管理机制(如Spring Session项目)没有直接关系。这个SessionLocaleResolver会根据当前的HttpServletRequest来评估和修改相应的HttpSession属性。
本地化拦截器
你可以通过在某个 HandlerMapping 定义中添加 LocaleChangeInterceptor 来启用语言环境的切换功能。该拦截器会检测请求中的参数,并据此更改语言环境,通过调用分发器应用上下文中的 LocaleResolver 的 setLocale 方法来实现这一操作。下一个示例表明,现在对所有包含名为 siteLanguage 的参数的 *.view 资源的请求都会导致语言环境的改变。例如,对于 URL [domain.com/home.view?siteLanguage=nl](https://domain.com/home.view?siteLanguage=nl) 的请求,网站的语言会切换为荷兰语。以下示例展示了如何拦截这种语言环境的变化:
- Java
- Kotlin
- Xml
@Configuration
public class WebConfiguration {
@Bean
public LocaleResolver localeResolver() {
return new CookieLocaleResolver();
}
@Bean
public SimpleUrlHandlerMapping urlMapping() {
SimpleUrlHandlerMapping urlHandlerMapping = new SimpleUrlHandlerMapping();
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("siteLanguage");
urlHandlerMapping.setInterceptors(interceptor);
urlHandlerMapping.setUrlMap(Map.of("/**/*.view", "someController"));
return urlHandlerMapping;
}
}
@Configuration
class WebConfiguration {
@Bean
fun localeResolver(): LocaleResolver {
return CookieLocaleResolver()
}
@Bean
fun urlMapping() = SimpleUrlHandlerMapping().apply {
setInterceptors(LocaleChangeInterceptor().apply {
paramName = "siteLanguage"
})
urlMap = mapOf("/**/*.view" to "someController")
}
}
<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>