likes
comments
collection
share

管理系统必备技(15): i18n 国际化使用

作者站长头像
站长
· 阅读数 11

一、前言

后端在发生异常时,应该把异常信息告诉给前端。

但是异常需要考虑前端的国际化情况,所以,异常需要做国际化处理。

管理系统必备技(15): i18n 国际化使用

像此类断言信息,如果要考虑国际化就不能这样写,需要自己封装返回消息体。

二、i18n 国际化使用姿势

Java中的 Locale.getDefault() 获取的是操作系统的默认区域设置,如果需要获取客户端浏览器的区域设置,可以从HTTP头中获取"Accept-Language"的值来进行解析。

以一个接口为例,所有的请求头都需设置上语言信息,后端才可以根据请求头的数据进行消息的返回。

管理系统必备技(15): i18n 国际化使用

2.1 配置类

在Java Web应用中使用MessageSource对象实现国际化功能时,可以通过以下步骤使用浏览器语言动态设置Locale区域。

  • 国际化文件在resources/i18n目录,文件名是message_{语言}.properties
  • 通过MessageSource对象进行国际化配置信息的管理
@Configuration
public class LocalMessageConfig {

   /**
    * 系统国际化文件配置
    * @return MessageSource
    */
   @Bean
   public MessageSource messageSource() {
      ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
      messageSource.setBasename("classpath:i18n/message");
      messageSource.setDefaultEncoding("UTF-8");
      return messageSource;
   }

}

2.2 消息工具类封装

@UtilityClass
public class MsgUtils {

   /**
    * 通过code 获取中文错误信息
    * @param code
    * @return
    */
   public String getMessage(String code) {
      MessageSource messageSource = SpringContextHolder.getBean("ocloudMessageSource");
      return messageSource.getMessage(code, null, Locale.CHINA);
   }

   /**
    * 通过code 和参数获取中文错误信息
    * @param code
    * @return
    */
   public String getMessage(String code, Object... objects) {
      MessageSource messageSource = SpringContextHolder.getBean("ocloudMessageSource");
      return messageSource.getMessage(code, objects, Locale.CHINA);
   }
}

我们自己封装一个工具类

通过 LocaleContextHolder.getLocale()获取客户端浏览器的语言环境,就是请求头中的Accept-Language的值,再根据它进行国际化消息的获取。

@UtilityClass
public class LocaleMessageUtils {
   /**
    * 通过code 获取错误信息
    * @param code
    * @return
    */
   public String getMessage(String code) {
      return getMessage(code, null);
   }

   /**
    * 通过code 和参数获取错误信息
    * @param code
    * @return
    */
   public String getMessage(String code, Object... objects) {
      MessageSource messageSource = SpringContextHolder.getBean("ocloudMessageSource");
      Locale locale = LocaleContextHolder.getLocale();
      return messageSource.getMessage(code, objects,locale);
   }
}

2.3 i18n 文件创建

1、配置文件,可以有多种,目前实现的有中文和英文。

可以打印出各语言的编码,在根据编码规则添加文件。

public void test1(){
   Locale chinaLocale = Locale.CHINA;
   Locale usLocale = Locale.US;
   System.out.println(chinaLocale);
   System.out.println(usLocale);
   /**
    * 输出结果如下:
    * zh_CN
    * en_US
    * 我们一般会将不同的语言的属性值存放在不同的配置文件中,
    * Properties配置文件命名规则:baseName_local.properties
    *  假如baseName为i18n,则相应的配置文件应该命名为如下:
    *
    * 中文的配置文件:i18n_zh_CN.properties
    *
    * 英文的配置文件:i18n_en_US.properties
    *
    */
}

2、在对应的微服务 resource 下建立文件

管理系统必备技(15): i18n 国际化使用

3、添加测试语言

中文

xiaolei.test= chinese test

英文

xiaolei.test= english test

2.4 测试

编写测试类

@RequestMapping("/hello")
@RestController
public class I18nController {

   @GetMapping
   public String msg(){
      String message = LocaleMessageUtils.getMessage("xiaolei.test");
      return message;
   }
}

中文传参:

管理系统必备技(15): i18n 国际化使用

英文传参:

管理系统必备技(15): i18n 国际化使用

具体的请求头详情可以查看这个链接。

developer.mozilla.org/zh-CN/docs/…

三、拓展优化

3.1 编码问题

前面的功能测试通过了,但是中文必须编码成 unicode 才能解析,而 unicode 对我们来说太不友好了。

管理系统必备技(15): i18n 国际化使用

解决方式:打开idea,把这个勾勾打上。

管理系统必备技(15): i18n 国际化使用

3.2 占位符使用

管理系统必备技(15): i18n 国际化使用

编码后,可以看到占位符有 {0} {1},

那我们再来测试下

修改编码为:

xiaolei.test=  来者何人{0},身高 {1}

按顺序传参

@RequestMapping("/hello")
@RestController
public class I18nController {

   @GetMapping
   public String msg(){
      String message = LocaleMessageUtils.getMessage("xiaolei.test","潇雷","1米八");
      return message;
   }
}

管理系统必备技(15): i18n 国际化使用

自动拼接成功。

综上,完成后端异常编码的国际化处理。