JAVA (Springboot) i18n国际化语言配置

JAVA i18n国际化语言配置

  • 一、简介
  • 二、功能
  • 三、Java配置国际化步骤
  • 四、Java国际化配置工具类
  • 五、Spring Boot配置
  • 六、测试

一、简介

在Java中,国际化(Internationalization,通常简称为i18n)是一个过程,它允许应用程序适应不同的语言和地区设置,从而能够支持全球用户。Java平台为国际化提供了强大的支持,包括Locale类、ResourceBundle类以及用于格式化日期、数字和货币的类。

二、功能

1.支持多语言:

应用程序可以显示多种语言的文本,包括但不限于英文、中文、法文等。
通过使用ResourceBundle,可以为每种语言提供独立的资源文件(通常是.properties文件),其中包含该语言的文本。

2.自动选择语言:
Java的Locale类允许应用程序根据用户的偏好或系统设置自动选择适当的语言。
例如,如果用户的操作系统设置为法语,那么应用程序将尝试加载法语的资源文件。格式化日期、数字和货币

3.用户手动切换语言:
应用程序通常还允许用户手动切换语言,即使他们的系统设置或浏览器默认语言不是他们想要使用的语言。这可以通过在应用程序中提供语言选择界面或设置选项来实现。

4.前后端文字、校验、消息提醒的国际化:
国际化不仅限于用户界面上的文本,还包括后端代码中的字符串、错误消息、验证提示等。
通过使用外部化的字符串和消息,可以确保整个应用程序的文本都是可翻译的。

5.通过AOP切面实现多语言的配置:
这是一个高级特性,允许开发人员使用面向切面编程(AOP)来自动处理对象的字符串属性,并根据配置文件中的语言设置进行替换。
这种方法可以确保即使在复杂的业务逻辑中,字符串也能被正确地翻译成用户所需的语言。
配置文件命名规则:
在Java国际化中,配置文件必须遵循特定的命名规则,以便Java能够正确识别。
例如,一个名为“messages”的资源束文件可以有以下命名的资源文件:messages.properties(默认)、messages_en_US.properties(英语(美国))、messages_fr_FR.properties(法语(法国))等。

三、Java配置国际化步骤

3.1 创建资源文件夹
在src/main/resources目录下新建一个文件夹,用于存放国际化配置文件。
例如,您可以创建一个名为i18n或messages的文件夹。

3.2 添加语言文件

3.2.1 选择Resource Bundle 进行添加配置文件

在这里插入图片描述
3.2.2 配置要添加的语言配置文件
在i18n或messages文件夹下,为每个要支持的语言和地区添加.properties文件。文件名的命名规则通常是basename_language_country.properties,其中basename是您的基本文件名(如messages),language是ISO 639语言代码(如en代表英语),country是ISO 3166国家代码(如US代表美国)。

例如:
messages_en_US.properties(美国英语)
messages_en_GB.properties(英国英语)
messages_zh_CN.properties(简体中文)
messages_zh_TW.properties(繁体中文,台湾)

(会有一个Default locale默认的语言配置文件)
在这里插入图片描述

3.2.3、 在对应的配置文件添加对应的语言信息

1.zh_CN:(中文)

sys.config.newParameters=新增参数
sys.config.changeParameters=修改参数
sys.config.newParametersExists=失败,参数键名已存在

2.en_US:(英文)

sys.config.newParameters=New parameters
sys.config.changeParameters=Modify parameters
sys.config.newParametersExists=Failed, parameter key name already exists

四、Java国际化配置工具类

4.1、创建MessageUtils工具类

MessageUtils 工具类在国际化(i18n)应用中扮演着非常重要的角色,它封装了与消息资源相关的常用操作,使得在应用程序的不同部分中都能够方便地获取和格式化本地化消息,而无需重复编写代码,通过key来获取目前系统语言的value值。

import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;/*** 获取i18n资源文件** @author cccl*/
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());}
}

4.2、添加国际化(i18n配置类)

import lombok.extern.slf4j.Slf4j; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.web.servlet.config.annotation.InterceptorRegistration; 
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/**  * 国际化(i18n)配置类  */  
@Configuration   
@Slf4j 
// 实现WebMvcConfigurer接口,用于自定义Spring MVC的配置  
public class I18nConfig implements WebMvcConfigurer { /**  * 添加拦截器到Spring MVC的拦截器链中  *  * @param registry 拦截器注册器,用于添加和配置拦截器  */  @Override  public void addInterceptors(InterceptorRegistry registry) {  // 创建一个自定义的国际化拦截器实例  MyI18nInterceptor myHandlerInterceptor = new MyI18nInterceptor();  // 使用拦截器注册器注册自定义的国际化拦截器  InterceptorRegistration loginRegistry = registry.addInterceptor(myHandlerInterceptor);  // 设置需要拦截的路径模式,这里配置为拦截所有路径("/**")  loginRegistry.addPathPatterns("/**");  }  }

4.3、添加国际化(i18n拦截器)

import com.github.pagehelper.util.StringUtil;
import lombok.extern.slf4j.Slf4j;  
import org.springframework.context.i18n.LocaleContextHolder;  
import org.springframework.web.servlet.HandlerInterceptor;  
import org.springframework.web.servlet.ModelAndView;  import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import java.util.Locale;  /**  * i18n拦截器:用于从HTTP请求头中获取国际化参数,并设置当前线程的Locale。  */  
@Slf4j  
public class MyI18nInterceptor implements HandlerInterceptor {  /**  * 在请求处理之前进行调用。  *  * @param request  HttpServletRequest对象,提供对客户端请求信息的访问  * @param response HttpServletResponse对象,提供对HTTP响应的控制  * @param handler  被调用的处理器,通常是HandlerMethod  * @return 如果返回false,则请求处理流程将被中断并返回给客户端;如果返回true,则继续执行后续流程  * @throws Exception 抛出异常将中断请求处理流程  */  @Override  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  // 假设请求头中存储语言信息的键名为"Language"  final String key = "Language"; // 从请求头中获取语言信息  String language = request.getHeader(key); // 使用自定义的字符串工具类判断语言信息是否非空  if (JoventStringUtils.isNotEmpty(language)) {// 假设语言信息格式为"zh_CN"或"en_US",这里通过下划线分割获取语言和地区信息  String[] languageParts = language.split("_");  // 确保分割后有两个部分  if (languageParts.length == 2) { // 创建Locale对象  Locale locale = new Locale(languageParts[0], languageParts[1]); // 设置当前线程的Locale  LocaleContextHolder.setLocale(locale); } else {  // 如果格式不正确,可以记录日志或进行其他处理  log.warn("Invalid language format: {}", language);  }  }  // 继续执行后续流程 return true;  }  /**  * 在请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)  * 通常用于处理一些需要在请求处理之后、视图渲染之前执行的逻辑  *  * @param request   HttpServletRequest对象  * @param response  HttpServletResponse对象  * @param handler   被调用的处理器  * @param modelAndView 如果处理器方法的返回值是ModelAndView类型,则为该方法的返回值,否则为null  */  @Override  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {  // 可以在这里添加处理请求处理之后、视图渲染之前的逻辑  }  /**  * 在整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图之后执行(主要是用于进行资源清理工作)  *  * @param request   HttpServletRequest对象  * @param response  HttpServletResponse对象  * @param handler   被调用的处理器  * @param ex        如果在请求处理过程中发生异常,则为该异常,否则为null  */  @Override  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {  // 可以在这里添加请求处理完毕后的清理逻辑,例如关闭资源等  }  
}

五、Spring Boot配置

spring:  # 资源信息配置  messages:  # 国际化资源文件的基础名称(不包含文件后缀),Spring将会在这个基础上添加语言代码和地区代码(例如messages_zh_CN.properties)来查找具体的资源文件  basename: i18n/messages # 国际化资源文件路径  # 当找不到特定Locale的资源文件时,是否回退到系统默认的Locale。如果设置为true,并且找不到特定Locale的资源文件,Spring将尝试使用系统默认的Locale来加载资源文件  fallback-to-system-locale: true # 回退到系统Locale  # 指定资源文件的编码格式。在读取资源文件时,Spring将使用此编码格式  encoding: UTF-8 # 编码格式  # 国际化资源文件的缓存时间(以秒为单位)。在这段时间内,相同的资源请求将不会再次加载资源文件,而是从缓存中获取。设置为-1将禁用缓存  cache-duration: 3600 # 缓存持续时间(秒)

六、测试

6.1、接口

@Log(title = "参数管理", businessType = BusinessType.INSERT)
@GetMapping("/add")
public AjaxResult add() {return AjaxResult.success(MessageUtils.message("sys.config.newParameters"));
}

此处截取的是请求头的Language参数,那么我们在请求的时候添加一个Language参数 (具体的截取字段名自行配置)

6.2 、英文请求(en_US)

在这里插入图片描述
6.3 、中文请求(zh_CN)
在这里插入图片描述

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

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

相关文章

【C语言项目】实现一个通讯录,一步一步详细讲解,小白也能看

目录 设计思路 代码实现 代码改造1 代码改造2 完整代码 代码仓库 设计思路 1. 通讯录存放的信息 这个通讯录保存的信息包括:名字,年龄,性别,电话,住址。 2. 通讯录的功能 1. 通讯录可以存放100个人的信息。 2…

2024年 Java 面试八股文(20w字)

> 🍅我是小宋, 一个只熬夜但不秃头的Java程序员。 > 🍅关注我,带你**过面试,读源码**。提升简历亮点(14个demo) > 🍅我的面试集已有12W 浏览量。 > 🌏号…

[C++] 深度剖析C_C++内存管理机制

文章目录 内存分布内存分布图解 C语言中动态内存管理方式malloc:callocrealloc C内存管理方式内置类型**自定义类型** operator new & operator deleteoperator new & operator delete函数operator newoperator delete **new T[N]** 与**delete[]** **定位new表达式(pl…

【C语言】指针由浅入深全方位详解!!!

目录 指针 野指针 二级指针 指针数组 字符指针 数组指针 数组参数,指针参数 函数指针 函数指针数组 回调函数 练习题 代码仓库 指针 1. 指针定义 1. 指针是内存中一个最小单元的编号,也就是地址。 2. 平时口语中说的指针&#xff…

【C++】如何巧妙运用C++命名空间:初学者必备指南

C语法相关知识点可以通过点击以下链接进行学习一起加油! 本篇将带领大家走进C的旅途,为了更好地学习C这门语言,我们需要了解它的前世今生。在了解完C如何诞生后,将开始我们C之旅第一站"命名空间"。(老早说是C/C博主&…

Java 集合框架:HashMap 的介绍、使用、原理与源码解析

大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 020 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进…

零基础入门转录组数据分析——GO+KEGG富集分析

零基础入门转录组数据分析——GOKEGG富集分析 目录 零基础入门转录组数据分析——GOKEGG富集分析1. 富集分析基础知识2. GO富集分析(Rstudio)——代码实操3. KEGG富集分析(Rstudio)——代码实操注:配套资源只要改个路径…

PyQt5| 界面设计 |利用Qt Designer实现简单界面交互

目录 1 QtDesigner简单界面设计2 代码部分2.1 ui文件转py文件2.2 界面文件代码2.3 主文件代码2.3.1 主体框架代码2.3.2 实现交互代码 3结果展示 准备工作: 配置好PyQt5相关的库、QtDesigner、pyuic 1 QtDesigner简单界面设计 点击“工具"——>“外部工具&a…

Matlab实现最小二乘法的几种方法

最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。 按照图中所提出的问题(如图1),要求已知多组解(自变量和因变量),求出最佳和最恰…

【C++/STL深度剖析】priority_queue 最全解析(什么是priority_queue? priority_queue的常用接口有哪些?)

目录 一、前言 二、如何区分【优先级队列】与【队列】? 三、priority_queue的介绍 四、priority_queue 的构造 五、priority_queue 的常用接口 💧push 💧pop 💧size 💧top 💧empty &…

C语言贪吃蛇课程设计实验报告(包含贪吃蛇项目源码)

文末有贪吃蛇代码全览,代码有十分细致的注释!!!文末有贪吃蛇代码全览,代码有十分细致的注释!!!文末有贪吃蛇代码全览,代码有十分细致的注释!!! 码文不易,给个免费的小星星和免费的赞吧,关注也行呀(⑅•͈ᴗ•͈).:*♡ 不要白嫖哇(⁍̥̥̥᷄д⁍̥̥…

【C++/STL】:vector容器的底层剖析迭代器失效隐藏的浅拷贝

目录 💡前言一,构造函数1 . 强制编译器生成默认构造2 . 拷贝构造3. 用迭代器区间初始化4. 用n个val值构造5. initializer_list 的构造 二,析构函数三,关于迭代器四,有关数据个数与容量五,交换函数swap六&am…

SpringBoot整合Flink CDC实时同步postgresql变更数据,基于WAL日志

SpringBoot整合Flink CDC实时同步postgresql变更数据,基于WAL日志 一、前言二、技术介绍(Flink CDC)1、Flink CDC2、Postgres CDC 三、准备工作四、代码示例五、总结 一、前言 在工作中经常会遇到要实时获取数据库(postgresql、m…

为何重视文件加密?用哪款加密软件好呢?

一、公司都重视文件加密的原因有哪些?保护数据安全:在数字化时代,数据是企业重要的资产之一。文件加密可以确保数据在存储和传输过程中不被未经授权的人员访问或窃取,从而保护数据的机密性和完整性。这对于包含敏感信息&#xff0…

Reat hook开源库推荐

Channelwill Hooks 安装 npm i channelwill/hooks # or yarn add channelwill/hooks # or pnpm add channelwill/hooksAPI 文档 工具 Hooks useArrayComparison: 比较两个数组的变化。useCommunication: 处理组件之间的通信。useCurrencyConverter: 货币转换工具。useCurre…

【Docomo】5G

我们想向您介绍第五代移动通信系统“5G”。 5G 什么是5G?支持5G的技术什么是 5G SA(独立)?实现高速率、大容量的5G新频段Docomo的“瞬时5G”使用三个宽广的新频段 什么是5G? 5G(第五代移动通信系统&#x…

【Elasticsearch】Elasticsearch的分片和副本机制

文章目录 📑前言一、分片(Shard)1.1 分片的定义1.2 分片的重要性1.3 分片的类型1.4 分片的分配 二、副本(Replica)2.1 副本的定义2.2 副本的重要性2.3 副本的分配 三、分片和副本的机制3.1 分片的创建和分配3.2 数据写…

Github Benefits 学生认证/学生包 新版申请指南

本教程适用于2024年之后的Github学生认证申请,因为现在的认证流程改变了很多,所以重新进行了总结这方面的指南。 目录 验证教育邮箱修改个人资料制作认证文件图片转换Base64提交验证 验证教育邮箱 进入Email settings,找到Add email address…

【一图学技术】5.OSI模型和TCP/IP模型关系图解及应用场景

OSI模型和TCP/IP模型关系图解 OSI模型和TCP/IP模型都是网络通信的参考模型,用于描述网络协议的层次结构和功能。下面是它们的定义和区别: OSI模型(Open Systems Interconnection Model) OSI模型是一个理论上的七层模型&#xff…

揭秘线性代数秩的奥秘:从理论到机器学习的跨越

一、线性代数中的秩:定义与性质 1.1 定义 在线性代数中,秩是一个核心概念,用于描述矩阵或向量组的复杂性和独立性。具体而言,一个矩阵的秩定义为该矩阵中非零子式的最高阶数,而一个向量组的秩则是其最大无关组所含的…