相关文章推荐
高大的椰子  ·  C# 窗口关闭事件 - ...·  9 月前    · 
纯真的马铃薯  ·  WaitForSingleObject ...·  1 年前    · 
独立的日记本  ·  React 16.x折腾记 - (4) ...·  1 年前    · 
首页 > 软件编程 > java > springboot i18n多语言设置

基于springboot i18n国际化后台多种语言设置的方式

作者:从心归零

这篇文章主要介绍了基于springboot i18n国际化后台多种语言设置的方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

之前有做过手机端后台的国际化,因为手机统一传递了language参数

所以只要设置LocaleChangeInterceptor就行了

* 配置国际化语言 @Configuration public class LocaleConfig extends WebMvcConfigurerAdapter{ * 默认解析器 其中locale表示默认语言 @Bean public LocaleResolver localeResolver() { SessionLocaleResolver localeResolver = new SessionLocaleResolver(); localeResolver.setDefaultLocale(Locale.CHINA); return localeResolver; //springboot1.5 @Override public void addInterceptors(InterceptorRegistry registry) { LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor(); localeInterceptor.setParamName("language"); registry.addInterceptor(localeInterceptor);

对于某些特殊的后台运行代码,比如定时器,我则使用getByLanguage方法

* 国际化工具类 @Component public class MessageUtils{ private static MessageSource messageSource; static SysErrorLogDao sysErrorLogDao; @Resource public void setSysErrorLogDao(SysErrorLogDao sysErrorLogDao) { MessageUtils.sysErrorLogDao = sysErrorLogDao; private static Logger logger = LoggerFactory.getLogger(MessageUtils.class); public MessageUtils(MessageSource messageSource) { MessageUtils.messageSource = messageSource; * 获取单个国际化翻译值 * @param msgKey * @param defaultMsg * @return public static String get(String msgKey, String defaultMsg) { try { return messageSource.getMessage(msgKey, null, LocaleContextHolder.getLocale()); } catch (Exception e) { logger.error(e.getMessage(), e); String message = StringUtils.getExceptionStackTraceMessage(e); if(message != null && message.length() > 1000) { message = message.substring(0, 999); SysErrorLogModel errorLog = new SysErrorLogModel(); errorLog.setContent(msgKey); errorLog.setType("messageUtils"); errorLog.setCreateDate(new Date()); errorLog.setClassName(MessageUtils.class.getName()); errorLog.setMessage(message); sysErrorLogDao.save(errorLog); return defaultMsg; * 获取多个参数取代的国际化翻译值 * @param msgKey * @param defaultMsg * @param arg * @return public static String get(String msgKey, String defaultMsg, Object... arg) { try { msgKey = messageSource.getMessage(msgKey, arg, LocaleContextHolder.getLocale()); return msgKey; } catch (Exception e) { logger.error(e.getMessage(), e); String message = StringUtils.getExceptionStackTraceMessage(e); if(message != null && message.length() > 1000) { message = message.substring(0, 999); SysErrorLogModel errorLog = new SysErrorLogModel(); errorLog.setContent(msgKey); errorLog.setType("messageUtils"); errorLog.setCreateDate(new Date()); errorLog.setClassName(MessageUtils.class.getName()); errorLog.setMessage(message); sysErrorLogDao.save(errorLog); return MessageFormat.format(defaultMsg, arg); * 指定语言获得单个国际化翻译值 * @param msgKey * @param defaultMsg * @param language * @return public static String getByLanguage(String msgKey, String defaultMsg, String language) { try { Locale locale = new Locale(language); msgKey = messageSource.getMessage(msgKey, null, locale); return msgKey; } catch (Exception e) { logger.error(e.getMessage(), e); String message = StringUtils.getExceptionStackTraceMessage(e); if(message != null && message.length() > 1000) { message = message.substring(0, 999); SysErrorLogModel errorLog = new SysErrorLogModel(); errorLog.setContent(msgKey); errorLog.setType("messageUtils"); errorLog.setCreateDate(new Date()); errorLog.setClassName(MessageUtils.class.getName()); errorLog.setMessage(message); sysErrorLogDao.save(errorLog); return defaultMsg; * 指定语言获取多参数取代的国际化翻译值 * @param msgKey * @param defaultMsg * @param language * @param arg * @return public static String getByLanguage(String msgKey, String defaultMsg, String language, Object... arg) { try { Locale locale = new Locale(language); msgKey = messageSource.getMessage(msgKey, arg, locale); return msgKey; } catch (Exception e) { logger.error(e.getMessage(), e); String message = StringUtils.getExceptionStackTraceMessage(e); if(message != null && message.length() > 1000) { message = message.substring(0, 999); SysErrorLogModel errorLog = new SysErrorLogModel(); errorLog.setContent(msgKey); errorLog.setType("messageUtils"); errorLog.setCreateDate(new Date()); errorLog.setClassName(MessageUtils.class.getName()); errorLog.setMessage(message); sysErrorLogDao.save(errorLog); return MessageFormat.format(defaultMsg, arg);

但是后面又要做网页的国际化,因为网页没有传递统一的语言参数,如果要一一添加的话太过麻烦,于是就要用到cookie来保存传递语言

这个时候就要实现自己的解析器了

public class MyLocaleResolver implements LocaleResolver { @Override public Locale resolveLocale(HttpServletRequest httpServletRequest) { Locale locale = Locale.getDefault(); //通过参数解析locale,language参数优先 String temp = httpServletRequest.getParameter("language"); if (!StringUtils.isEmpty(temp)) { locale = new Locale(temp); return locale; //得到cookie,解析locale Cookie[] cookies = httpServletRequest.getCookies(); if(cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals("userLanguage")) { String temp = cookie.getValue(); if (!StringUtils.isEmpty(temp)) { locale = new Locale(temp); continue; return locale; @Override public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { @Configuration public class LocaleConfig extends WebMvcConfigurerAdapter{ @Bean public LocaleResolver localeResolver() { MyLocaleResolver localeResolver = new MyLocaleResolver(); return localeResolver;

这样就实现了使用cookie来设置语言

不过最后还是有所遗漏,因为我们的分布式项目中用到了很多http的内部调用,用不上cookie,也没有language参数。

但是大部分的内部调用都有传递公司id,可以通过公司获得公司对应的语言。

可以在拦截器里面直接加入对companyId的解析但是我考虑有没有通用的实现方法,就是在任何地方,甚至的运行到一半中途设置语言的办法。

初步想法是拿到线程中的Locale进行设置

然后我看了下源码LocaleContextHolder.getLocale()

发现调用的是一个LocaleContext类的方法。

然后查询哪些地方调用了LocaleResolver.resolveLocale

发现第一个方法里面返回了一个匿名函数LocaleContext,其getLocale就是直接调用localeResolver.resolveLocale方法。

于是我合理的猜想框架里不是通过拦截器设置一个locale,而是每次调用LocaleContextHolder.getLocale()都会执行localeResolver.resolveLocale(request)方法,所以我们只要设置request属性就行了

public class MyLocaleResolver implements LocaleResolver { @Override public Locale resolveLocale(HttpServletRequest httpServletRequest) { //得到cookie,解析locale Locale locale = Locale.getDefault(); //通过参数解析locale String temp = httpServletRequest.getParameter("language"); if (!StringUtils.isEmpty(temp)) { locale = new Locale(temp); return locale; String temp = (String) httpServletRequest.getAttribute("language"); if (!StringUtils.isEmpty(temp)) { locale = new Locale(temp); return locale; Cookie[] cookies = httpServletRequest.getCookies(); if(cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals("userLanguage")) { String temp = cookie.getValue(); if (!StringUtils.isEmpty(temp)) { locale = new Locale(temp); continue; return locale; @Override public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { @RequestMapping("/test") public String test(HttpServletRequest request) { String result = ""; request.setAttribute("language", "ch"); result += MessageUtils.get("test", "测试"); request.setAttribute("language", "en"); result += MessageUtils.get("test", "测试"); return result;

messages_ch.properties

test=测试

messages_en.properties

test=test

这样我们就实现了在任何地点,甚至中途变换语言了

发现LocaleContextHolder.getLocale()在实体类中也可以调用。因此可以后台保存json格式,在get方法中根据语言返回相应的值。

我本来想直接改造原来的字段,但是发现缓存会直接读取get中的值,下次读取就不是json了,所以只好麻烦点增加一个字段了

public String getFullNameByLanguage() { String language = LocaleContextHolder.getLocale().getLanguage(); Map<String, String> map; try { map = JsonUtil.string2Obj(fullName); return map.get(language); } catch (IOException e) { return fullName;

当使用@Async异步方法时,LocaleContext就是空的。这时候需要强制设置语言LocaleContextHolder.setLocale(Locale locale),当然一般的方法也可以用这个来设置语言,不过这样的话就不会再调用localeResolver.resolveLocale(request)方法了

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
  • tk-mybatis整合springBoot使用两个数据源的方法
    tk-mybatis整合springBoot使用两个数据源的方法
    2021-12-12
  • 使用@Valid+BindingResult进行controller参数校验方式
    使用@Valid+BindingResult进行controller参数校验方式
    2021-12-12
  • jmeter接口测试教程及接口测试流程详解(全网仅有)
    jmeter接口测试教程及接口测试流程详解(全网仅有)
    2021-12-12
  • Mybatis执行Update返回行数为负数的问题
    Mybatis执行Update返回行数为负数的问题
    2021-12-12
  • mybatisplus @Select注解中拼写动态sql异常问题的解决
    mybatisplus @Select注解中拼写动态sql异常问题的解决
    2021-12-12
  • Java如何实现读取txt文件内容并生成Word文档
    Java如何实现读取txt文件内容并生成Word文档
    2021-12-12
  • 详细解读Java Spring AOP
    详细解读Java Spring AOP
    2021-12-12
  • mybatis新增save结束后自动返回主键id详解
    mybatis新增save结束后自动返回主键id详解
    2021-12-12
  • 美国设下计谋,用娘炮文化重塑日本,已影响至中国
    美国设下计谋,用娘炮文化重塑日本,已影响至中国
    2021-11-19
  • 时空伴随者是什么意思?时空伴随者介绍
    时空伴随者是什么意思?时空伴随者介绍
    2021-11-09
  • 工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
    工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
    2021-11-05
  • 2022年放假安排出炉:五一连休5天 2022年所有节日一览表
    2022年放假安排出炉:五一连休5天 2022年所有节日一览表
    2021-10-26
  • 电脑版 - 返回首页

    2006-2023 脚本之家 JB51.Net , All Rights Reserved.
    苏ICP备14036222号