一、前言
后端在发生异常时,应该把异常信息告诉给前端。
但是异常需要考虑前端的国际化情况,所以,异常需要做国际化处理。
像此类断言信息,如果要考虑国际化就不能这样写,需要自己封装返回消息体。
二、i18n 国际化使用姿势
Java中的 Locale.getDefault() 获取的是操作系统的默认区域设置,如果需要获取客户端浏览器的区域设置,可以从HTTP头中获取"Accept-Language"的值来进行解析。
以一个接口为例,所有的请求头都需设置上语言信息,后端才可以根据请求头的数据进行消息的返回。
2.1 配置类
在Java Web应用中使用MessageSource对象实现国际化功能时,可以通过以下步骤使用浏览器语言动态设置Locale区域。
- 国际化文件在resources/i18n目录,文件名是message_{语言}.properties
- 通过MessageSource对象进行国际化配置信息的管理
java
@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 消息工具类封装
typescript
@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的值,再根据它进行国际化消息的获取。
typescript
@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、配置文件,可以有多种,目前实现的有中文和英文。
可以打印出各语言的编码,在根据编码规则添加文件。
ini
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 下建立文件
3、添加测试语言
中文
ini
xiaolei.test= chinese test
英文
ini
xiaolei.test= english test
2.4 测试
编写测试类
less
@RequestMapping("/hello")
@RestController
public class I18nController {
@GetMapping
public String msg(){
String message = LocaleMessageUtils.getMessage("xiaolei.test");
return message;
}
}
中文传参:
英文传参:
具体的请求头详情可以查看这个链接。
developer.mozilla.org/zh-CN/docs/...
三、拓展优化
3.1 编码问题
前面的功能测试通过了,但是中文必须编码成 unicode 才能解析,而 unicode 对我们来说太不友好了。
解决方式:打开idea,把这个勾勾打上。
3.2 占位符使用
编码后,可以看到占位符有 {0} {1},
那我们再来测试下
修改编码为:
ini
xiaolei.test= 来者何人{0},身高 {1}
按顺序传参
less
@RequestMapping("/hello")
@RestController
public class I18nController {
@GetMapping
public String msg(){
String message = LocaleMessageUtils.getMessage("xiaolei.test","潇雷","1米八");
return message;
}
}
自动拼接成功。
综上,完成后端异常编码的国际化处理。