前言
最近项目推广到了海外,领导要求把公司项目陆续都做国际化,之前学过一些有点印象,网上又看了点资料,大概是知道怎么做,不过项目中需要转换的中文太多,踩了不少坑,才拿出相对方便的转换解决国际化的方法。
主要是通过messageSource,然后在需要国际化的地方调用工具类方法,通过cookie中的国际化变量选择对应Locale,最后去读国际化配置文件。
介绍国际化的帖子有很多这边不在赘述,主要给出国际化转换中各种方便快速转换工具类方法和思路,其中逻辑只是繁琐不复杂可根据业务自行修改
目录
1、效果示例
前端切换
切换结果会放到cookie中
后端国际化文件(英文配置文件可以通过接口调用和io处理统一翻译)
2、工具类和配置类
2.1 国际化的转换类
需要做国际化的转换类调用I18nUtil.chooseLanguageCoverMsg(原中文值)
@Slf4j
public class I18nUtil {
//java中使用java.util.Locale来表示地区语言这个对象
public static Locale getLocale() {
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attrs != null) {
HttpServletRequest request = attrs.getRequest();
// 获取所有的 cookies
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
// 可以根据 cookie 的名字来处理特定的 cookie
if (Constants.COOKIE_I18N.equals(cookie.getName())) {
String cookieValue = cookie.getValue();
// 对特定 cookie 值的处理...
if (StringUtils.isNotBlank(cookieValue)) {
if (Constants.COOKIE_I18N_EN.equals(cookieValue)) {
return Locale.US;
}//为cn就是 默认 都用中文
}
}
}
}
}
return Locale.CHINA;
}
//选择国家化语言后进行文字转换
public static String chooseLanguageCoverMsg(String message) {
if (StringUtils.isBlank(message)) {
return message;
}
String coverLanguageMsg = null;
try {
ApplicationContext applicationContext = SpringContextHolder.getApplicationContext();
Locale locale = I18nUtil.getLocale();
coverLanguageMsg = applicationContext.getMessage(message, null, locale);
} catch (Exception e) {
log.info("国际化转换类异常:" + e);
return message;
}
if (StringUtils.isBlank(coverLanguageMsg)) {
return message;
}//如果没有配置国际化 就用原本的值
return coverLanguageMsg;
}
}
2.2 配置类自定义messageSource
重点注意messageSource.setDefaultEncoding("UTF-8");注意:这样项目做国际化的值可以直接用原来的中文了,做国际化转换力求对原项目的业务逻辑侵入达到最小
/**
* 自定义messageSource开启国际化,spring容器启动时会加载messageSource,如果没有自定义会加载默认
* 可以自定义ResourceBundle 指定加载properties文件读取编码为utf-8,这样就不用改动枚举和常量源文件了,在配置文件中直接用个人中心=personal center
*/
@Configuration
public class MessageSourceConfig {
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
//可以指定国际化化配置文件的位置,格式:路径/文件名称,注意不包含【语言_国家.properties】含这部分
messageSource.setBasenames("conf/i18n/message"); //@1
messageSource.setDefaultEncoding("UTF-8"); // 设置默认编码为 UTF-8
messageSource.setFallbackToSystemLocale(false);
messageSource.setUseCodeAsDefaultMessage(true);
messageSource.setFallbackToSystemLocale(false);
// messageSource.setB(new CustomResourceBundleControl("UTF-8")); // 使用自定义的 ResourceBundle.Control
return messageSource;
}
}
2.3 剩余的处理类
i18nConvertUtil 国际化转换-异常转换类 i18nConvertUtil2 国际化转换-枚举转换类 i18nConvertUtil3 国际化转换-excel转换类 TranslateApi2 翻译类-调用有道接口进行批量翻译生成message_en_US.properties文件TranslateApi3 翻译工具类优化-1去重,如果有多个重复值去重不输出 2会生成中文配置文件, 如果只有一个中文的时候会变成中文=中文 多的不说直接上代码
3、github地址
GitHub - dragon2030/SSM-template at i18n_20240306
项目中数据转换方式
除非是常量类和魔法值,不然尽量不要直接把国际化的转换写到业务代码中,带来很大的代码侵入
系统可以录入的可以不做国际化,系统不能修改的数据库内容,建议用mybatis拦截器处理。后续会补这块代码