SpringMVC部署至日文Windows Server2016时LocaleResolver语言切换失效
我之前碰到过类似跨Windows版本的Locale配置坑,结合你的场景,大概率是系统区域设置或Tomcat默认Locale继承导致的SessionLocaleResolver失效,给你几个针对性的排查和解决步骤:
1. 强制Tomcat使用指定Locale启动
日文Windows Server的系统默认Locale是ja_JP,Tomcat启动时会直接继承这个系统Locale,很可能覆盖你SessionLocaleResolver设置的默认配置。你可以在Tomcat的catalina.bat中添加JVM启动参数,强制锁定默认语言环境:
set JAVA_OPTS=%JAVA_OPTS% -Duser.language=en -Duser.region=US
这样Tomcat启动时就会以英文Locale为基础,避开系统Locale对SessionLocaleResolver的干扰。
2. 补全LocaleChangeInterceptor配置
看你代码里只写了addInterc...,应该是没写完LocaleChangeInterceptor的注册逻辑——这个拦截器是实现语言切换的核心,必须正确配置才能让请求参数触发Locale更新:
@Override public void addInterceptors(InterceptorRegistry registry) { LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor(); localeInterceptor.setParamName("lang"); // 定义切换语言的请求参数名,比如?lang=ja切换日语、?lang=en切换英语 registry.addInterceptor(localeInterceptor); }
一定要确保这个拦截器被正确注册到Spring MVC的拦截器链中,否则请求中的语言参数根本不会被解析并同步到Session里。
3. 检查系统"非Unicode程序语言"设置
日文Windows Server默认会把「控制面板→时钟和区域→区域→管理」里的「非Unicode程序的语言」设为日文,这会直接影响JVM获取Locale的逻辑。你可以:
- 把这个选项改为「英语(美国)」,重启服务器后再测试;
- 如果不想改系统设置,直接用第一步的JVM启动参数强制覆盖即可,效果是一样的。
4. 调试Locale的实际变化状态
在Controller里加个简单的调试接口,打印当前Locale,确认语言切换是否真的生效:
@GetMapping("/debug/locale") @ResponseBody public String debugCurrentLocale() { Locale currentLocale = LocaleContextHolder.getLocale(); return String.format("当前Locale: %s | 显示名称: %s", currentLocale.toString(), currentLocale.getDisplayName()); }
调用这个接口时传入语言参数(比如/debug/locale?lang=ja),如果返回的Locale没变化,说明拦截器没生效;如果Locale变了但页面没切换,那就是国际化资源文件的问题。
5. 确保国际化资源文件编码正确
日文的messages_ja.properties如果用了Shift-JIS编码,在不同系统下可能出现加载异常。建议统一用UTF-8编码资源文件,并在MessageSource配置里明确指定编码:
@Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); messageSource.setDefaultEncoding("UTF-8"); messageSource.setUseCodeAsDefaultMessage(true); return messageSource; }
这样Spring就能正确读取日文资源文件,不会因为编码问题导致语言切换后显示异常。
先从前两步排查,一般就能解决大部分系统Locale干扰的问题,如果还有问题,再通过调试接口定位具体环节。
内容的提问来源于stack exchange,提问作者tiepvut

