spring boot 应用中配置了 `localeresolver` 和 `localechangeinterceptor`,也指定了 `spring.messages.basename`,但通过 `?lang=en` 切换语言无效——根本原因常在于资源文件命名不匹配、拦截器未生效、或消息源加载路径错误,而非单纯 url 参数格式问题。
要使 Spring Boot 的国际化(i18n)真正生效,需确保四个核心环节全部正确协同工作:Locale 解析器注册、语言切换拦截器启用、消息资源文件规范命名与位置、以及模板中正确使用消息表达式。以下为经过验证的完整配置指南:
你已实现该 Bean,但建议显式指定 setLocaleAttributeName 并确保其在 @Configuration 类中被扫描到(避免因组件扫描遗漏导致未生效):
@Configuration
public class WebConfig {
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver resolver = new SessionLocaleResolver();
resolver.setDefaultLocale(Locale.forLanguageTag("pl")); // 推荐用 forLanguageTag 更安全
resolver.setLocaleAttributeName("session.locale"); // 显式设置属性名,便于调试
return resolver;
}
}⚠️ 注意:@Configuration 类必须被 Spring 容器加载(如主启动类位于同包或子包下,或通过 @ComponentScan 显式引入)。
你当前在 WebMvcConfigurer 实现类中定义了 localeChangeInterceptor() 方法,但该方法未加 @Bean 注解,导致 Spring 不会将其作为 Bean 管理,addInterceptors() 中实际传入的是一个普通对象实例,无法被 Spring AOP 拦截链识别。
✅ 正确写法(推荐统一在 @Configuration 类中声明):
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setPara
mName("lang"); // 对应 ?lang=en
return interceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor()).excludePathPatterns("/resources/**", "/static/**");
}
}? 提示:excludePathPatterns 可避免对静态资源重复触发拦截,提升性能。
同时确保 application.properties 中配置无拼写错误且已生效:
# application.properties spring.messages.basename=errors-messages,labels spring.messages.encoding=UTF-8 spring.messages.cache-duration=3600
? 验证技巧:启动应用后访问 /actuator/env,搜索 spring.messages.basename,确认值已正确加载。
在 HTML 模板中使用 #{key} 语法,而非 ${message} 或硬编码文本:
Welcome
© 2025
Welcome
logging.level.org.springframework.web.servlet.i18n=DEBUG logging.level.org.springframework.context.support=DEBUG
日志中将输出 Locale resolved to [en] 或 No message found under code... 等关键线索。
按以上步骤逐一核对,99% 的 Spring Boot i18n 失效问题可立即解决。