还是直接上代码
目前实现了 中英文 返回 别的语言 都差不多
主要用spring boot 自带的 类实现的 不用引入任何 依赖
使用的就是下面的类
org.springframework.context.MessageSource 是 Spring Framework 中用于支持国际化(Internationalization,简称 i18n)的接口之一。它提供了一种统一的方式来获取文本信息,使得应用程序能够根据不同的语言和区域设置展示对应的文本内容。
具体来说,MessageSource 接口定义了一组方法,可以根据指定的消息代码(message code)和可选的参数获取相应的本地化文本消息。这些消息通常存储在配置文件中,通过配置管理器(如 ApplicationContext)加载并提供给应用程序使用。
在 Spring 应用中,通常会将不同语言版本的文本消息存储在不同的 properties 文件中,然后通过 MessageSource 接口来动态加载并根据当前用户的语言环境提供相应的文本信息,从而实现国际化功能。
第一步 配置文件
package com.xx.init.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;import java.util.Locale;/*** User:Json* Date: 2024/4/20**/
@Configuration
public class LocaleConfig {//这里的配置文件 也可以写在 application.yml 中@Beanpublic ResourceBundleMessageSource messageSource() {Locale.setDefault(Locale.CHINA);ResourceBundleMessageSource source = new ResourceBundleMessageSource();//设置国际化文件存储路径和名称// i18n目录,messages文件名//Spring Boot 会根据不同的语言环境自动加载对应的资源文件,// 例如 messages_zh_CN.properties 或 messages_en_US.propertiessource.setBasenames("i18n/messages");//设置根据key如果没有获取到对应的文本信息,则返回key作为信息source.setUseCodeAsDefaultMessage(true);//设置字符编码source.setDefaultEncoding("UTF-8");return source;}}
一般项目 都会装这个插件 不解释了
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
创建中英文配置文件之前 看一下编辑器有没有 设置UTF-8 防止乱码
创建 这个后缀的文件 .properties
中英文:
messages_zh_CN.properties 或 messages_en_US.properties
最后样子
第二步创建 枚举类 定义 项目使用了哪些语言
package com.xx.init.language;import lombok.AllArgsConstructor;
import lombok.Getter;/*** User:Json* Date: 2024/4/20**/
@Getter
@AllArgsConstructor
public enum LanguageEnum {ZH_CN("zh_CN", "中文/中国"),EN("en_US", "英语/美国"),;/*** 格式 是 语言_国家 缩写* 更多国家 java.util.Locale; 可以查看这个类里的*/private String name;/*** 描述*/private String desc;
}
第三步 编写工具类
package com.xx.init.utils;import cn.hutool.extra.spring.SpringUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.context.MessageSource;
import org.springframework.util.StringUtils;import java.util.Locale;/*** User:Json* Date: 2024/4/20**/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class LanguageUtil {/*** 根据key信息获取对应语言的内容** @param key 消息key值* @param language 语言_国家* @return*/public static String get(String key, String language) {if (!StringUtils.isEmpty(language)) {String[] arrs = language.split("_");if (arrs.length == 2) {return get(key, new Locale(arrs[0], arrs[1]));}}//使用默认的国际化语言return get(key, Locale.getDefault());}/*** 根据key信息获取对应语言的内容** @param key 消息key值* @param params 需要替换到占位符中的参数 占位符下标重0开始 格式如: {0} {1}* @param language 语言_国家* @return*/public static String get(String key, Object[] params, String language) {if (!StringUtils.isEmpty(language)) {String arrs[] = language.split("_");if (arrs.length == 2) {return get(key, params, new Locale(arrs[0], arrs[1]));}}return get(key, params, Locale.getDefault());}private static String get(String key, Locale language) {return get(key, new String[0], language);}private static String get(String key, Object[] params, Locale language) {return getInstance().getMessage(key, params, language);}private static MessageSource getInstance() {return Lazy.messageSource;}/*** 使用懒加载方式实例化messageSource国际化工具*/private static class Lazy {private static final MessageSource messageSource = SpringUtil.getBean(MessageSource.class);}}
第四步 编写测试配文文件
在中英文配置文件中 写两句 话 {0} 占位符 不需要就不写
第五步 拦截器获取前端 语言类型 这个大家哪获得都行
LanguageType.setLanguage 我定义的存储方式
// 用的是 ThreadLocal 用完 别忘了 释放
//如果ThreadLocal存放的数据不释放,当用户量大的时候会导致系统出现OOM问题
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {LanguageType.setLanguage(StringUtils.isEmpty(request.getHeader("language")) ? LanguageEnum.ZH_CN.getName() : request.getHeader("language"));}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {//会话结束移除线程缓存LanguageType.removeLanguage();}
第六步 :ThreadLocal 存储前端发来的 语言类型
package com.xx.init.language;/*** User:Json* Date: 2024/4/20**/
public class LanguageType{private static ThreadLocal<String> language = new ThreadLocal<String>();public static void setLanguage(String lang) {language.set(lang);}public static String getLanguage() {return language.get();}public static void removeLanguage() {language.remove();}}
测试控制器
@GetMapping("index15")@ApiOperation(value = "中文/英文测试")@PassTokenpublic R index15(){String s = LanguageUtil.get("test",new Object[]{"JAVA"}, LanguageType.getLanguage());return R.success(s);}// LanguageType.getLanguage() 这个方法 我是从 拦截器 请求头里 获取 前端传入的语言类型
// 比如前端传个 zh_CN 就是 中文 en_US 就是英文 // 建议前端传的这个 和 LanguageEnum 枚举类里定义的 一样// test 就是对应配置文件的 key
结果输出