国际化解析器设计

LocaleResolver 接口详解与策略对比
1. 接口作用与核心实现类
- 接口作用:确定当前用户的区域(
Locale
),用于国际化(如语言、日期格式等)。 - 核心实现类:
实现类名 决定 Locale
的依据特点 AcceptHeaderLocaleResolver
HTTP请求头 Accept-Language
默认策略,无需配置,但用户无法主动切换语言 CookieLocaleResolver
浏览器 Cookie 持久化用户语言偏好(跨会话) SessionLocaleResolver
HTTP Session 会话内持久化,会话失效后丢失 FixedLocaleResolver
固定 Locale
强制固定区域,不可切换
2. 完整示例代码与配置
策略1:AcceptHeaderLocaleResolver
作用:根据浏览器语言设置决定区域。
配置类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
@Configuration
public class AcceptHeaderConfig {
@Bean
public AcceptHeaderLocaleResolver localeResolver() {
AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
resolver.setDefaultLocale(Locale.US); // 默认语言为英语
return resolver;
}
}
测试请求:
# 请求头设置为中文
curl -H "Accept-Language: zh-CN" "http://localhost:8080/greeting"
# 返回:你好,用户!
# 请求头设置为西班牙语
curl -H "Accept-Language: es" "http://localhost:8080/greeting"
# 返回:Hola, usuario!
策略2:CookieLocaleResolver
作用:通过 Cookie 持久化用户语言偏好。
配置类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
@Configuration
public class CookieConfig {
@Bean
public CookieLocaleResolver localeResolver() {
CookieLocaleResolver resolver = new CookieLocaleResolver();
resolver.setCookieName("LOCALE"); // Cookie 名称
resolver.setCookieMaxAge(3600); // 有效期 1小时
resolver.setDefaultLocale(Locale.US); // 默认语言
return resolver;
}
}
控制器设置语言:
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController
public class CookieController {
@GetMapping("/set-locale/{lang}")
public String setLocale(@PathVariable String lang, HttpServletRequest request) {
Locale targetLocale = "es".equals(lang) ? Locale.forLanguageTag("es") : Locale.CHINA;
CookieLocaleResolver resolver = new CookieLocaleResolver(); // 假设已注入
resolver.setLocale(request, null, targetLocale); // 设置 Cookie
return "语言已切换为:" + lang;
}
}
测试步骤:
-
切换语言:
curl -X GET "http://localhost:8080/set-locale/es" # 设置为西班牙语
-
发送请求(Cookie 自动携带):
curl -H "Cookie: LOCALE=es" "http://localhost:8080/greeting" # 返回:Hola, usuario!
策略3:SessionLocaleResolver
作用:通过 HTTP Session 持久化用户语言偏好(会话内有效)。
配置类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
@Configuration
public class SessionConfig {
@Bean
public SessionLocaleResolver localeResolver() {
SessionLocaleResolver resolver = new SessionLocaleResolver();
resolver.setDefaultLocale(Locale.US); // 默认语言
return resolver;
}
}
控制器设置语言:
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
@RestController
public class SessionController {
@GetMapping("/set-locale/{lang}")
public String setLocale(@PathVariable String lang, HttpSession session) {
Locale targetLocale = "es".equals(lang) ? Locale.forLanguageTag("es") : Locale.CHINA;
session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, targetLocale);
return "语言已切换为:" + lang;
}
}
测试步骤:
-
切换语言:
curl -X GET "http://localhost:8080/set-locale/zh" # 设置为中文
-
发送请求(需保持 Session ID):
curl -b "JSESSIONID=12345" "http://localhost:8080/greeting" # 返回:你好,用户!
策略4:FixedLocaleResolver
作用:强制固定区域,不可切换。
配置类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.i18n.FixedLocaleResolver;
@Configuration
public class FixedConfig {
@Bean
public FixedLocaleResolver localeResolver() {
FixedLocaleResolver resolver = new FixedLocaleResolver();
resolver.setLocale(Locale.GERMANY); // 固定为德语
return resolver;
}
}
测试请求:
curl "http://localhost:8080/greeting"
# 返回:Hallo, Benutzer!(假设德语消息存在)
3. 对比表格:四种策略总结
策略名称 | 决定 Locale 的依据 | 持久化方式 | 适用场景 | 配置复杂度 |
---|---|---|---|---|
AcceptHeader | HTTP头 Accept-Language | 无持久化 | 无需用户干预,快速生效 | 简单(默认) |
Cookie | 浏览器 Cookie | 跨会话持久化 | 需要长期保存用户偏好(如电商) | 中(需设置 Cookie 参数) |
Session | HTTP Session | 会话内持久化 | 短期用户偏好(如登录用户) | 中(依赖 Session) |
Fixed | 固定值 | 无 | 单语言环境(如政府网站) | 超简单 |
4. 常见问题
-
Q:如何自定义
LocaleResolver
的优先级?
A:通过@Order
注解或WebMvcConfigurer
的addInterceptors
方法调整优先级。 -
Q:如何同时支持 URL 参数切换语言?
A:结合LocaleChangeInterceptor
,示例:@Configuration public class MvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LocaleChangeInterceptor()) .addPathPatterns("/**"); // 通过 ?lang=es 参数切换 } }
5. 完整配置示例
# application.properties(Spring Boot)
# 设置默认语言
spring.mvc.locale=es
# 设置 Cookie 名称(如使用 `CookieLocaleResolver`)
spring.mvc.locale-resolver.cookie-name=LOCALE
spring.mvc.locale-resolver.cookie-max-age=3600
提示:实际开发中,通常结合 CookieLocaleResolver
或 SessionLocaleResolver
,并提供前端语言切换按钮(如 <a href="?lang=zh">中文</a>
)。