SpringBoot 接口国际化i18n 多语言返回 中英文切换 全球化 语言切换

介绍

Spring Boot通过MessageSource接口来实现国际化,它可以加载不同的消息资源文件,通常是.properties格式。通过定义不同的语言文件(例如:messages_en.properties、messages_zh.properties等),可以根据用户的语言环境来自动选择对应的文件,提供不同的翻译和文本来实现业务的国际化操作。

效果

英文

{"msg": "success","code": 200,"data": null
}

中文

{"msg": "操作成功","code": 200,"data": null
}

其他语言也可以自行配置

配置文件

spring:messages:# 国际化资源文件路径basename: i18n/messages

在这里插入图片描述
messages表示匹配以messages开头的文件

创建语言文件

message.properties
公共的语言文件

system.error.tip=请联系管理员操作

messages_en_US.properties
英文语言文件

system.user.tip.name=Please enter the user name
system.user.tip.password=Please enter the user password

messages_zh_CN.properties
中文语言文件

system.user.tip.name=请输入用户名
system.user.tip.password=请输入用户密码

多语言情况下请保持语言文件的格式和字段

拦截器配置

这个拦截器主要识别前端传递的语言字符串并根据字符串返回对应的语言

/*** 该类是一个自定义的拦截器,用于从HTTP请求的头部获取语言参数,并根据该参数设置当前请求的语言。* 它继承自Spring的`LocaleChangeInterceptor`,并重写了`preHandle`方法来实现自定义的语言切换逻辑。*/
public class CustomLocaleChangeInterceptor extends LocaleChangeInterceptor {// 设置请求头中获取语言的字段名private static final String LANG_HEADER = "lang";/*** 这个方法会在每个请求处理之前被调用,用来获取请求头中的语言设置,* 如果存在有效的语言参数,就会设置当前请求的语言环境。* @param request  当前的HTTP请求对象* @param response 当前的HTTP响应对象* @param handler  当前请求的处理器(一般是控制器方法)* @return 如果返回true,表示继续执行后续的处理器链,否则会中断请求的处理*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 从请求头中获取指定的语言字段("lang")String lang = request.getHeader(LANG_HEADER);// 如果lang参数存在且不为空if (lang != null && !lang.isEmpty()) {// 按照"-"分割语言和地区信息String[] parts = lang.split("_");// 设置语言环境// parts[0]是语言(例如:en、zh)// parts[1]是地区(例如:US、CN),如果没有地区则使用空字符串LocaleContextHolder.setLocale(new Locale(parts[0], parts.length > 1 ? parts[1] : ""));}// 返回true放行return true;}
}

还有一种方法可以从浏览器自带的:Accept-Language:zh-CN,zh;q=0.9 来获取但是各浏览器的参数有所不同所以没采用,好处就是可以自动识别用户的语言。

I18n配置类

/*** 资源文件配置加载* 该配置类用于设置国际化资源文件的加载和管理。它配置了语言环境解析器以及自定义的拦截器。* 通过此配置,Spring Web应用能够根据用户的请求来切换不同的语言环境(Locale)。*/
@Configuration
public class I18nConfig implements WebMvcConfigurer {/*** 定义一个 LocaleResolver bean,用于处理当前用户会话中的语言环境。* * LocaleResolver 用于解析当前请求的语言环境,通常会根据Session中的信息来判断。* 在这里我们使用的是 SessionLocaleResolver,它会将用户选择的语言存储在Session中,* 这样用户在后续请求中可以保持相同的语言环境。** @return 返回配置好的 LocaleResolver*/@Beanpublic LocaleResolver localeResolver() {// 创建一个 SessionLocaleResolver 实例SessionLocaleResolver slr = new SessionLocaleResolver();// 设置默认的语言环境为简体中文 (zh_CN)// 当用户没有明确设置语言时,应用默认使用简体中文slr.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);return slr;}/*** 配置国际化拦截器,用于监听用户请求中的语言切换参数。** 该方法会添加一个自定义的拦截器 CustomLocaleChangeInterceptor,目的是监听用户请求中的语言切换请求,* 并更新当前会话的语言环境。** @param registry 拦截器注册器*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册自定义的语言环境切换拦截器// 该拦截器会监听请求中是否包含语言参数(例如:?lang=zh_CN),// 如果有,就会根据该参数改变当前用户的语言环境。registry.addInterceptor(new CustomLocaleChangeInterceptor());}
}

封装Bean工具类

该代码来着若依管理系统

/*** spring工具类,方便在非Spring管理环境中获取bean* 提供一些用于获取Spring上下文中的Bean,环境配置,AOP代理对象等功能的方法。* 该类实现了 BeanFactoryPostProcessor 和 ApplicationContextAware 接口,* 用于在非Spring管理环境中操作Spring容器中的bean。** @author ruoyi*/
@Component
public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware
{/** Spring应用上下文环境的BeanFactory */private static ConfigurableListableBeanFactory beanFactory;/** Spring应用上下文环境 */private static ApplicationContext applicationContext;/*** 实现 BeanFactoryPostProcessor 接口的 postProcessBeanFactory 方法* 用于在Spring容器启动时获取Spring容器中的BeanFactory。** @param beanFactory Spring的BeanFactory* @throws BeansException 如果发生异常*/@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException{SpringUtils.beanFactory = beanFactory;  // 保存 BeanFactory 实例}/*** 实现 ApplicationContextAware 接口的 setApplicationContext 方法* 用于在Spring容器启动时获取Spring应用上下文环境。** @param applicationContext Spring的应用上下文* @throws BeansException 如果发生异常*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException{SpringUtils.applicationContext = applicationContext;  // 保存应用上下文实例}/*** 根据bean名称获取Spring容器中的Bean实例** @param name bean的名称* @return 返回与给定名称相对应的bean实例* @throws org.springframework.beans.BeansException 如果没有找到bean实例*/@SuppressWarnings("unchecked")public static <T> T getBean(String name) throws BeansException{return (T) beanFactory.getBean(name);  // 获取bean}/*** 根据给定的bean类型获取Spring容器中的Bean实例** @param clz bean的类型* @return 返回与给定类型相对应的bean实例* @throws org.springframework.beans.BeansException 如果没有找到bean实例*/public static <T> T getBean(Class<T> clz) throws BeansException{T result = (T) beanFactory.getBean(clz);  // 根据类型获取beanreturn result;}/*** 检查BeanFactory中是否包含指定名称的Bean定义** @param name bean的名称* @return 如果包含该bean,返回true,否则返回false*/public static boolean containsBean(String name){return beanFactory.containsBean(name);  // 检查bean是否存在}/*** 判断指定名称的bean是singleton类型还是prototype类型* 如果指定名称的bean没有定义,将抛出NoSuchBeanDefinitionException异常。** @param name bean的名称* @return 如果是singleton类型返回true,prototype类型返回false* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException 如果没有找到该bean*/public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException{return beanFactory.isSingleton(name);  // 判断bean类型}/*** 获取指定名称bean的类型* 如果没有找到bean,将抛出NoSuchBeanDefinitionException异常。** @param name bean的名称* @return 返回指定bean的类型* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException 如果没有找到该bean*/public static Class<?> getType(String name) throws NoSuchBeanDefinitionException{return beanFactory.getType(name);  // 获取bean的类型}/*** 获取指定名称bean的别名* 如果该bean有别名,则返回所有别名,否则返回空数组。** @param name bean的名称* @return 返回该bean的所有别名* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException 如果没有找到该bean*/public static String[] getAliases(String name) throws NoSuchBeanDefinitionException{return beanFactory.getAliases(name);  // 获取bean的别名}/*** 获取当前bean的AOP代理对象* 通过AOP上下文获取代理对象,并返回代理对象或原始bean实例。** @param invoker 需要代理的bean实例* @return 返回代理对象或者原始对象*/@SuppressWarnings("unchecked")public static <T> T getAopProxy(T invoker){Object proxy = AopContext.currentProxy();  // 获取当前的AOP代理if (((Advised) proxy).getTargetSource().getTargetClass() == invoker.getClass()){return (T) proxy;  // 如果是代理类,返回代理对象}return invoker;  // 否则返回原始对象}/*** 获取当前的激活环境配置* 如果有多个激活环境配置,返回所有的配置。** @return 返回当前的所有激活环境配置*/public static String[] getActiveProfiles(){return applicationContext.getEnvironment().getActiveProfiles();  // 获取当前环境配置}/*** 获取配置文件中的某个key对应的值* 从环境配置中获取指定的属性值,如果没有找到该key,会抛出异常。** @param key 配置文件中的key* @return 返回配置文件中指定key对应的值*/public static String getRequiredProperty(String key){return applicationContext.getEnvironment().getRequiredProperty(key);  // 获取配置项的值}
}

封装语言工具类

/*** 获取i18n资源文件*/
public class MessageUtils
{/*** 根据消息键和参数 获取消息 委托给spring messageSource** @param code 消息键* @param args 参数* @return 获取国际化翻译值*/public static String message(String code, Object... args){MessageSource messageSource = SpringUtils.getBean(MessageSource.class);return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());}}

接口使用

@RequestMapping("/user")
public R user() {return R.success(I18NUtils.message("system.user.tip.name"));
}

前端请求

lang:en_US
返回英文

lang:zh_CN
返回中文

在请求头中携带

传入参数

语言文件
system.user.tip.name=请输入用户名:{0}

后端使用

System.out.println(I18NUtils.message("system.user.tip.name","admin"));

输出结果

请输入用户名:admin

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

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

相关文章

一个crackme例子

文件下载地址&#xff1a;https://download.csdn.net/download/m0_37567738/90713354 将cipher.txt文件内容解密后&#xff1a; 恭喜你解出了这一关&#xff0c;flag为 zjwa{36_23121136a28d0d15} 好了现在告诉你最后一层的获取方式&#xff0c; 在系统内找到 手机镜像的 ra…

账户解封无望?3步高效申诉取回亚马逊冻结资金

近年来&#xff0c;随着全球跨境电商市场的飞速扩张&#xff0c;亚马逊&#xff08;Amazon&#xff09;作为其中的巨头&#xff0c;持续强化其平台治理力度。然而&#xff0c;随之而来的是卖家账户因各种原因被冻结、关闭的事件频频发生。根据Marketplace Pulse发布的2024年第一…

【C++ Qt】快速上手 显⽰类控件(Label、LCDNumber、ProcessBar、CalendarWidget)

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本文围绕Qt中常用的显示类控件展开&#xff0c;重点讲解了 QLabel&#xff08;文本/图片显示&#xff09;、QLCDNumber&#xff08;数字显示&#xff0…

从困局到破局的AI+数据分析

从困局到破局的AI数据分析 困局&#xff1a;数据分析的四道高墙破局&#xff1a;AI赋能全流程数据分析远见&#xff1a;AI数据分析的革命性意义 数据是新时代的石油&#xff0c;人工智能是炼油厂。当两者强强联合&#xff0c;一场数据分析的革命正悄然发生。 多少次你面对Excel…

IGH 汇川SV660N调试

EoE 目前的方式是将eoe 关闭, 这需要重新配置编译ec_master sudo ./configure --disable-8139too --enable-generic --enable-r8169 --disable-eoe --enable-coe[426163.348589] EtherCAT 0: Master thread exited. [426163.348592] EtherCAT 0: Stopping EoE thread. [426163.…

Java基础361问第16问——枚举为什么导致空指针?

我们看一段代码 public enum Color {RED, BLUE, YELLOW;public static Color parse(String color) {return null;} }public static void main() {Color color Color.parse("");// 极具迷惑性&#xff0c;大家日常开发肯定这么写过switch (color) {case RED:break;c…

10.Excel:快速定位目标值

一 批量删除 1.如何使用 快捷键 CTRLG 补充&#xff1a;直接选择定位条件。 2.作用 1.批量删除工作表中的图片 补充&#xff1a;无法通过框选的方式选中这些图片进行删除。 这样只框选了表格&#xff0c;无法框选图片。因为图片在excel中被认为是一个对象&#xff0c;对象无法通…

快乐数(双指针解法)

题目链接202. 快乐数 - 力扣&#xff08;LeetCode&#xff09; 题目拆解 1 取一个正整数每一位的平方和为&#xff0c;如果为1那么直接可以判定为快乐数&#xff0c;如果不为1&#xff0c;就重复这个过程&#xff0c;直到出现1 2 实际上&#xff0c;这道题只有两种情况&#xf…

进程控制的学习

进程控制&#xff08;Process Control&#xff09;是指操作系统对进程的创建、执行、暂停、恢复、终止等一系列状态变化进行管理和协调的过程。 简单说&#xff0c;就是系统让各个程序能有序地运行&#xff0c;合理地使用CPU和资源&#xff0c;而不会互相冲突或者出错。 主要包…

818协议知识笔记

一、概念 Fibre CHannel-Audio Vedio standard;FC-AV FC-FS:Fibre channel framing and signaling interface; FC-PI:fibre channel physical interfaces 二、术语 VGA,SVGA,XGA,WXGA,SXGA,SXGA,WSXGA,UXGA,1440P; ICD:interface control document接口控制文档 CRC对帧头和数据…

AI大模型学习十二:‌尝鲜ubuntu 25.04 桌面版私有化sealos cloud + devbox+minio对象存储测试和漫长修改之路

一、说明 前面已经安装完成&#xff0c;这里我们测试对象存储 AI大模型学习十一&#xff1a;‌尝鲜ubuntu 25.04 桌面版私有化sealos cloud devboxminio&#xff0c;实战运行成功-CSDN博客https://blog.csdn.net/jiangkp/article/details/147424823?spm1011.2415.3001.5331 二…

SpringBoot的自动扫描特性-笔记

1.Spring Boot 的自动扫描特性介绍 Spring Boot 的自动扫描&#xff08;Component Scanning&#xff09;是其核心特性之一。通过注解SpringBootApplication 简化了 Bean 的管理&#xff0c;允许框架自动发现并注册带有特定注解的类为 Spring 容器中的 Bean&#xff08;特定注解…

基于nodeJS代码的通过爬虫方式实现tiktok发布视频(2025年4月)

1、将真实的tiktokstudio平台的cookie填到代码里的cookie变量里,修改python代码里的ticket,ts, privateKey,以及videoPath,timing等变量的值,最后运行python脚本即可; 2、运行之前根据import提示安装一些常见依赖,比如node-fetch等; 3、运行时候可能系统需要科学上网…

数据一致性问题剖析与实践(四)——竞态条件竞争导致的一致性问题

一、前言 之前我们讨论了几种场景的一致性问题 冗余数据存储中的一致性问题分布式共识中的一致性问题单机事务中的一致性问题分布式事务中的一致性问题 本文将围绕竞态条件竞争中的一致性问题展开讨论分析。 二、 问题定义 竞态条件&#xff08;Race Condition&#xff09…

PCL点云处理之基于FPFH特征的SAC-IA全局配准算法 (二百四十六)

提示: 有相关点云需求的可以私信 PCL 点云处理之基于 FPFH 特征的 SAC - IA 全局配准算法 一、前言二、相关概念介绍2.1 点云2.2 FPFH 特征2.3 SAC - IA 算法三、SAC - IA 全局配准算法原理3.1 FPFH 特征提取3.2 SAC - IA 配准过程四、代码实现与分析4.1 完整代码4.2 代码分析…

JavaScript性能优化实战:从瓶颈定位到极致提速

JavaScript作为现代Web应用的核心&#xff0c;其性能直接影响用户体验。本文将从性能瓶颈定位、高频优化场景、现代API利用三个维度&#xff0c;结合代码示例和Chrome DevTools实战&#xff0c;为你构建完整的性能优化体系。 一、性能分析&#xff1a;精准定位瓶颈 1.1 Chrome…

JavaScript 页面刷新:从传统到现代的全面解析

在 Web 开发中&#xff0c;"刷新"是一个基础但极其重要的功能。本文将全面探讨页面刷新的实现方式&#xff0c;从传统方法到现代最佳实践&#xff0c;深入解析每一种方案的原理和适用场景&#xff0c;并给出实用代码示例。 一、理解页面刷新的本质 在 Web 开发中&am…

NLP高频面试题(五十五)——DeepSeek系列概览与发展背景

大型模型浪潮背景 近年来,大型语言模型(Large Language Model, LLM)领域发展迅猛,从GPT-3等超大规模模型的崛起到ChatGPT的横空出世,再到GPT-4的问世,模型参数规模和训练数据量呈指数级增长。以GPT-3为例,参数高达1750亿,在570GB文本数据上训练,显示出模型规模、数据…

鸿蒙系统应用开发全栈指南

一、开发环境搭建与工具链配置 1. DevEco Studio深度解析 作为鸿蒙生态的官方IDE&#xff0c;DevEco Studio 4.2版本已集成ArkTS 3.0编译器与AI代码助手功能。安装过程需注意&#xff1a; 系统要求&#xff1a;Windows 10 21H2或macOS Monterey以上环境依赖&#xff1a;Node…

iOS18 MSSBrowse闪退

iOS18 MSSBrowse闪退 问题方案结果 问题 最近升级了电脑系统(15.4.1)&#xff0c;并且也升级了xcode(16.3)开发工具。之后打包公司很早之前开发的项目。 上线之后发现在苹果手机系统18以上&#xff0c;出现了闪退问题。 涉及到的是第三方MSSBrowse&#xff0c;在选择图片放大的…