LocaleContextResolver实现多语言切换-笔记

news2025/5/17 17:43:30

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(用于加载国际化资源文件)
    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:CustomMessages"); // 指定国际化资源文件的前缀
        messageSource.setDefaultEncoding("UTF-8"); // 设置编码
        return messageSource;
    }

    // 2. 配置 LocaleResolver(用于解析语言环境)
    // 这里使用 LocaleContextResolver 的实现类 SessionLocaleResolver
    @Bean
    public LocaleResolver localeResolver() {
        // 使用 Session 存储 Locale,避免每次请求传递参数
        SessionLocaleResolver resolver = new SessionLocaleResolver();
        //设置默认语言为中文(zh_CN)
        resolver.setDefaultLocale(Locale.CHINA);
        return resolver;
    }

    // 3. 配置 LocaleChangeInterceptor(用于通过 URL 参数切换语言)
    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        // 通过 URL 参数(如 xxx?lang=zh-CN)切换语言
        LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
        interceptor.setParamName("lang");// 设置参数名
        return interceptor;
    }

    //4. 将 LocaleChangeInterceptor 添加到拦截器中,使其生效
    @Override
    public 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 {
    @Autowired
    private MessageSource messageSource;

    public String getLocalizedMessage(String code) {
        // 从 LocaleContext 中获取当前线程的 Locale
        Locale 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 {
    @Autowired
    private 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 上下文的一致性,从而实现灵活的国际化支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2377857.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Zephyr OS Nordic芯片的Flash 操作

目录 概述 1. 软硬件环境 1.1 软件开发环境 1.2 硬件环境 2 Flash操作库函数 2.1 nRF52832的Flash 2.2 Nordic 特有的 Flash 操作 2.2.1 nrfx_nvmc_bytes_write 函数 2.2.2 nrfx_nvmc_page_erase函数 2.2.3 nrfx_nvmc_write_done_check 函数 3 操作Flash的接口函数…

uv python 卸载

又是查了半天 官网wiki没有 网上一堆傻子胡说 uv提示也不对 AI还在这尼玛胡编乱造 开始 我原来装了这几个环境 uv python list 现在python3.7.7不需要了,卸载,直接 uv python uninstall 3.7.7 去找你自己要卸载的版本号,不需要整个包名复制…

浮点数截断法:四舍五入的精确模拟

理论解释: 1. 目标 假设 a 3.14159,我们想四舍五入到 小数点后两位(即 3.14 或 3.15)。 2. 步骤拆解 (1) a * 100 把 a 放大 100 倍,让小数点后两位变成整数部分: 3.14159 * 100 314.159 (2) 0.5 关…

技术文章:解决汇川MD500系列变频器干扰问题——GRJ9000S EMC滤波器的应用

1. 引言 汇川MD500系列变频器(Variable Frequency Drive, VFD)以其高性能、宽功率范围(0.4kW-500kW)和灵活的控制方式,广泛应用于工业自动化领域,如风机、水泵、传送带和压缩机等。然而,MD500系…

大模型数据分析破局之路20250512

大模型数据分析破局之路 本文面向 AI 初学者、数据分析从业者与企业技术负责人,围绕大模型如何为数据分析带来范式转变展开,从传统数据分析困境谈起,延伸到 LLM MCP 的协同突破,最终落脚在企业实践建议。 🌍 开篇导语…

基于javaweb的SSM驾校管理系统设计与实现(源码+文档+部署讲解)

技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…

Java内存泄露生产环境排查过程,通透了

昨天线上环境崩了 java堆内存溢出。。。 报错:java.lang.OutOfMemoryError: Java heap space 下面我将我排查问题的思路和过程记录了下来 1. 场景 客户端跟Java服务端通过websocket连接建立长链接并发送语音数据(text格式)Java服务端跟听…

NHANES指标推荐:MDS

文章题目:The association between magnesium depletion score (MDS) and overactive bladder (OAB) among the U.S. population DOI:10.1186/s41043-025-00846-x 中文标题:美国人群镁耗竭评分 (MDS) 与膀胱过度活动症…

【HTML5学习笔记1】html标签(上)

web标准(重点) w3c 构成:结构、表现、行为,结构样式行为相分离 结构:网页元素整理分类 html 表现:外观css 行为:交互 javascript html标签 1.html语法规范 1) 所有标签都在…

计算机视觉---目标检测(Object Detecting)概览

一、目标检测定义与核心任务 1. 定义 任务:在图像/视频中定位并分类所有感兴趣目标,输出边界框(Bounding Box)和类别标签。核心输出: 坐标:((x_1, y_1, x_2, y_2))(左上角右下角)或…

在vue3中使用Cesium的保姆教程

1. 软件下载与安装 1. node安装 Vue.js 的开发依赖于 Node.js 环境,因此我们首先需要安装 Node.js。Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它允许你在服务器端运行 JavaScript 代码,同时也为前端开发提供了强大的工具支…

IP地址、端口、TCP介绍、socket介绍、程序中socket管理

1、IP地址:IP 地址就是 标识网络中设备的一个地址,好比现实生活中的家庭地址。IP 地址的作用是 标识网络中唯一的一台设备的,也就是说通过IP地址能够找到网络中某台设备。 2、端口:代表不同的进程,如下图: 3、socket:…

搭建运行若依微服务版本ruoyi-cloud最新教程

搭建运行若依微服务版本ruoyi-cloud 一、环境准备 JDK > 1.8MySQL > 5.7Maven > 3.0Node > 12Redis > 3 二、后端 2.1数据库准备 在navicat上创建数据库ry-seata、ry-config、ry-cloud运行SQL文件ry_20250425.sql、ry_config_20250224.sql、ry_seata_2021012…

RK3568-鸿蒙5.1与原生固件-扇区对比分析

编译生成的固件目录地址 ../openharmony/out/rk3568/packages/phone/images鸿蒙OS RK3568固件分析 通过查看提供的信息,分析RK3568开发板固件的各个组件及其用途: 主要固件组件 根据终端输出的文件列表,RK3568固件包含以下关键组件&#x…

常见激活函数——作用、意义、特点及实现

文章目录 激活函数的意义常见激活函数及其特点1. Sigmoid(Logistic 函数、S型函数)2. Tanh(双曲正切函数)3. ReLU(Rectified Linear Unit修正线性单元)4. Softmax5. Swish(Google 提出&#xff…

基于微信小程序的在线聊天功能实现:WebSocket通信实战

基于微信小程序的在线聊天功能实现:WebSocket通信实战 摘要 本文将详细介绍如何使用微信小程序结合WebSocket协议开发一个实时在线聊天功能。通过完整的代码示例和分步解析,涵盖界面布局、WebSocket连接管理、消息交互逻辑及服务端实现,适合…

小波变换+注意力机制成为nature收割机

小波变换作为一种新兴的信号分析工具,能够高效地提取信号的局部特征,为复杂数据的处理提供了有力支持。然而,它在捕捉数据中最为关键的部分时仍存在局限性。为了弥补这一不足,我们引入了注意力机制,借助其能够强化关注…

【无标题】威灏光电哲讯科技MES项目启动会圆满举行

5月14日,威灏光电与哲讯科技MES项目启动会在威灏光电总部隆重举行。威灏光电董事长江轮、总经理刘明星、哲讯科技总经理崔新华、副总王子文及双方项目组成员共同出席,标志着两家企业在数字化领域的第二次深度合作正式启航。 强强联手,二度合作…

display:grid网格布局属性说明

网格父级 &#xff1a;display:grid&#xff08;块级网格&#xff09;/ inline-grid&#xff08;行内网格&#xff09; 注意&#xff1a;当设置网格布局&#xff0c;column、float、clear、vertical-align的属性是无效的。 HTML: <ul class"ls02 f18 mt50 sysmt30&…

排序算法之高效排序:快速排序,归并排序,堆排序详解

排序算法之高效排序&#xff1a;快速排序、归并排序、堆排序详解 前言一、快速排序&#xff08;Quick Sort&#xff09;1.1 算法原理1.2 代码实现&#xff08;Python&#xff09;1.3 性能分析 二、归并排序&#xff08;Merge Sort&#xff09;2.1 算法原理2.2 代码实现&#xf…