区域解析 (Locale)
Spring 的架构全面支持国际化,DispatcherServlet 允许你根据客户端的区域设置(Locale)自动解析消息。这是通过 LocaleResolver 对象实现的。
常用 LocaleResolver 实现
| 实现类 | 策略说明 |
|---|---|
AcceptHeaderLocaleResolver | 默认实现。检查请求头中的 accept-language。不支持修改 Locale。 |
CookieLocaleResolver | 检查客户端浏览器存储的 Cookie。如果存在则使用,支持通过代码修改并持久化到 Cookie。 |
SessionLocaleResolver | 将 Locale 存储在 HttpSession 中。设置是临时性的,会话结束即失效。 |
时区支持 (Time Zone)
LocaleContextResolver 接口扩展了 LocaleResolver,允许解析器提供包含时区信息的 LocaleContext。你可以通过 RequestContext.getTimeZone() 获取用户的时区。
区域拦截器 (LocaleChangeInterceptor)
你可以通过配置 LocaleChangeInterceptor 允许用户通过请求参数手动更改语言。
java
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
return new CookieLocaleResolver(); // 使用 Cookie 存储
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang"); // 参数名:?lang=zh_CN
registry.addInterceptor(lci);
}
}kotlin
@Configuration
class WebConfiguration : WebMvcConfigurer {
@Bean
fun localeResolver(): LocaleResolver = CookieLocaleResolver()
override fun addInterceptors(registry: InterceptorRegistry) {
val lci = LocaleChangeInterceptor()
lci.paramName = "lang"
registry.addInterceptor(lci)
}
}补充教学
1. 国际化的“三剑客”
要实现完整的国际化,你需要三样东西:
- 资源文件 (Messages.properties):存储不同语言的文本。
- ResourceBundleMessageSource:用于加载这些资源文件的 Bean。
- LocaleResolver:决定当前请求该用哪种语言。
2. 为什么选 Cookie 而不是 Session?
- SessionLocaleResolver:用户关掉浏览器再进来,语言设置就丢了。且在集群环境下需要 Session 共享。
- CookieLocaleResolver:推荐做法。它可以设置有效期(如一年),这样用户下次访问时,依然能保持上次选择的预设语言,体验更好。
3. 如何在代码中获取 Locale?
不要直接从 Request 获取,因为那样可能拿不到拦截器修改后的 Locale。 正确方法:
java
Locale locale = LocaleContextHolder.getLocale();Spring 会在请求处理过程中将当前的 Locale 存入这个 ThreadLocal 变量中,方便你在 Service 层甚至任何地方随时获取。