一、前言
後端在發生異常時,應該把異常資訊告訴給前端。
但是異常需要考慮前端的國際化情況,是以,異常需要做國際化處理。
像此類斷言資訊,如果要考慮國際化就不能這樣寫,需要自己封裝傳回消息體。
二、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;
}
}
自動拼接成功。
綜上,完成後端異常編碼的國際化處理。