当前位置: 首页 > news >正文

LocaleContextResolver实现多语言切换-笔记

1. LocaleContextResolver功能简介

org.springframework.web.servlet.LocaleContextResolver是 Spring MVC 中用于解析和管理用户 Locale(语言环境) 的核心接口。

//LocaleContextResolver 接口定义
public interface LocaleContextResolver extends LocaleResolver {LocaleContext resolveLocaleContext(HttpServletRequest var1);void setLocaleContext(HttpServletRequest var1, @Nullable HttpServletResponse var2, @Nullable LocaleContext var3);
}//LocaleResolver 定义
public interface LocaleResolver {Locale resolveLocale(HttpServletRequest var1);void setLocale(HttpServletRequest var1, @Nullable HttpServletResponse var2, @Nullable Locale var3);
}

它的主要作用是:

  1. 解析请求中的 Locale 信息
    从 HTTP 请求中提取用户指定的语言/地区信息(如 URL 参数、请求头、Cookie 等)。

  2. 维护 Locale 上下文
    将解析后的 Locale 信息存储在当前线程的上下文中(LocaleContext),确保整个请求链(如 Controller、视图渲染)使用一致的 Locale。

  3. 支持多级存储策略
    提供多种实现类,支持基于请求头、会话(Session)、Cookie 或固定值的 Locale 解析。

常见 LocaleContextResolver 实现类:

实现类特点
AcceptHeaderLocaleResolver从 HTTP 请求头 Accept-Language 解析 Locale。
SessionLocaleResolver

从Session中解析Locale;将 Locale 存储在用户 Session 中,适合需要持久化语言偏好的场景。

CookieLocaleResolver从Cookie中解析Locale;将 Locale 存储在 Cookie 中,适合无状态或分布式系统。
FixedLocaleResolver固定使用一个 Locale(如开发环境调试)。

典型使用场景

场景描述
国际化支持根据用户选择的语言显示不同的界面内容(如中英文切换)。
动态语言切换用户通过 URL 参数(如 ?lang=zh-CN)或按钮切换语言。
自动语言检测通过浏览器的 Accept-Language 请求头自动识别用户语言偏好。
持久化语言偏好使用 Cookie 或 Session 保存用户的语言选择,避免重复传递参数。

2. 用法演示

下面用一个例子演示使用 LocaleContextResolver 实现多语言切换功能,根据当前语言环境返回国际化消息,动态适配用户的语言偏好。

2.1 完整代码

step1. 配置 LocaleContextResolver 和拦截器

import java.util.Locale;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;@Configuration
public class WebLocalConfig implements WebMvcConfigurer {// 1. 配置 MessageSource(用于加载国际化资源文件)@Beanpublic MessageSource messageSource() {ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();messageSource.setBasename("classpath:CustomMessages"); // 指定国际化资源文件的前缀messageSource.setDefaultEncoding("UTF-8"); // 设置编码return messageSource;}// 2. 配置 LocaleResolver(用于解析语言环境)// 这里使用 LocaleContextResolver 的实现类 SessionLocaleResolver@Beanpublic LocaleResolver localeResolver() {// 使用 Session 存储 Locale,避免每次请求传递参数SessionLocaleResolver resolver = new SessionLocaleResolver();//设置默认语言为中文(zh_CN)resolver.setDefaultLocale(Locale.CHINA);return resolver;}// 3. 配置 LocaleChangeInterceptor(用于通过 URL 参数切换语言)@Beanpublic LocaleChangeInterceptor localeChangeInterceptor() {// 通过 URL 参数(如 xxx?lang=zh-CN)切换语言LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();interceptor.setParamName("lang");// 设置参数名return interceptor;}//4. 将 LocaleChangeInterceptor 添加到拦截器中,使其生效@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(localeChangeInterceptor());}
}

step2.根据Locale解析对应的国际化语言

Service 层使用 LocaleContextHolder 获取上下文中的 Locale,并根据Locale解析对应的国际化语言

import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;@Service
public class MessageService {@Autowiredprivate MessageSource messageSource;public String getLocalizedMessage(String code) {// 从 LocaleContext 中获取当前线程的 LocaleLocale currentLocale = LocaleContextHolder.getLocale();// 打印当前语言环境System.out.println("Current Locale: " + currentLocale);System.out.println("Trying to get message for code: " + code); // 打印 key//根据 Locale 从对应的资源文件中加载code的值return messageSource.getMessage(code, null, currentLocale);}
}

step3. 新建测试Controller

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class GreetingController {@Autowiredprivate MessageService messageService;@GetMapping("GreetingController/greet")public String greet() {// 获取国际化消息return messageService.getLocalizedMessage("greeting.message");}}

 step4. 配置国际化资源文件

  • CustomMessages_zh_CN.properties(中文)
    • greeting.message=你好,世界

  • CustomMessages_en_US.properties (英文)
    • greeting.message=hello,world

资源位置:

  • src/main/resources/
    ├── CustomMessages_en_US.properties        // 英文
    ├── CustomMessages_zh_CN.properties        // 中文
    

step5. 测试

case1. 不设定 lang参数,默认为中文。

  • 浏览器访问:http://127.0.0.1:8080/GreetingController/greet,输入如下:

case2. lang参数设为 zh_CN,输出结果为中文

  • 浏览器访问:http://127.0.0.1:8080/GreetingController/greet?lang=zh_CN,输入如下:

case3. lang参数设为 en_US,输出结果为英文

  • 浏览器访问:http://127.0.0.1:8080/GreetingController/greet?lang=en_US,输入如下:

2.2 代码流程简介

上述流程的核心原理简述:

  • LocaleContextResolver 负责从请求中解析出 Locale(如 URL 参数、请求头、Session、Cookie 等)。这里用的实现类为SessionLocaleResolver, 即WebLocalConfig#localeResolver方法中配置。
  • 解析出的 Locale 会通过 LocaleContextHolder.setLocale(...) 设置到当前线程的上下文中。
  • 后续的组件(这里对应MessageService,也能是Controller或视图)可以直接从 LocaleContextHolder.getLocale() 获取当前的 Locale,实现上下文一致性。

通过 LocaleContextResolver,Spring MVC 提供了灵活的国际化支持机制。开发者可以根据业务需求选择不同的 Resolver 实现,结合 LocaleChangeInterceptor 实现语言切换,使用LocaleContextHolder维护整个请求生命周期中 Locale 上下文的一致性,从而实现灵活的国际化支持。

相关文章:

  • MySQL8新特性
  • 通过python安装小智语音服务器端
  • window nvidia-smi命令 Failed to initialize NVML: Unknown Error
  • Elabscience 精准识别 CD4+ T 细胞|大鼠源单克隆抗体 GK1.5,适配小鼠样本的流式优选方案
  • 强化学习算法实战:一个例子搞懂sarsa、dqn、ddqn、qac、a2c及其区别
  • 【生成式AI文本生成实战】DeepSeek系列应用深度解析
  • 读取toml, 合并,生成新文件
  • 最新开源 TEN VAD 与 Turn Detection 让 Voice Agent 对话更拟人 | 社区来稿
  • 【C++】STL简介
  • FC7300 ADC MCAL配置引导
  • 启用rvzi可视化自己的机器人发现joint state publisher gui没有滑块
  • 数据服务共享平台方案
  • 轨道炮--范围得遍历,map巧统计
  • 蓝牙协议架构与调试工具详解(含 BLE、HCI 命令、调试命令)
  • 25年2月通信基础知识补充2:延迟对齐调制、常见卫星移动速度
  • 方法区与元空间解析
  • Reth(冗余以太网接口) 和Bridge-Aggregation(链路聚合接口)区别
  • Spring模拟转账开发
  • Python爬虫(28)Python爬虫高阶:Selenium+Splash双引擎渲染实战与性能优化
  • LangGraph 官方文档翻译 - 快速入门及示例教程(聊天、工具、记忆、人工干预、自定义状态、时间回溯)
  • 上海公办小学验证今起开始,下周一和周二分区进行民办摇号
  • 被围观的“英之园”,谁建了潮汕天价违建?
  • “80后”萍乡市安源区区长邱伟,拟任县(区)委书记
  • 武大校长:人工智能不存在“过度使用”,武大不会缩减文科
  • 小米汽车机盖门陷谈判僵局,车主代表称小米表示“退订会造成崩塌”
  • 最高人民法院、中国证监会联合发布《关于严格公正执法司法 服务保障资本市场高质量发展的指导意见》