Wisper是一個(gè)輕量級(jí)I18n翻譯框架,簡(jiǎn)單易用,性能出色,并且擴(kuò)展簡(jiǎn)單。
讓我們看看如何開始使用Whisper!
假設(shè)你有一個(gè)基于Spring的項(xiàng)目,并且項(xiàng)目的dataSource已經(jīng)配置好。
可以在下面鏈接得到Whisper的樣例代碼
準(zhǔn)備工作
創(chuàng)建I18n翻譯表
在你的服務(wù)基于的數(shù)據(jù)庫(kù)中,創(chuàng)建一張i18n表,用來存儲(chǔ)翻譯關(guān)系。
如果恰好使用Mysql,你可以直接使用以下腳本創(chuàng)建這張表:
CREATE TABLE `i18n_item` (
`i18n_key` varchar(36) NOT NULL,
`language` varchar(20) NOT NULL,
`i18n_code` varchar(45) NOT NULL,
`i18n_name` longtext,
`is_enabled` bigint(1) NOT NULL,
`is_deleted` bigint(1) NOT NULL,
`created_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY `index_key_lang_code` (`i18n_key`,`language`,`i18n_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
其余數(shù)據(jù)庫(kù)的實(shí)現(xiàn)我們后續(xù)會(huì)很快給出,也歡迎大家貢獻(xiàn)其他庫(kù)的實(shí)現(xiàn)方式。
添加Maven依賴
將Whisper的Maven依賴加入到項(xiàng)目中。
<dependency>
<groupId>io.github.benhouse1987</groupId>
<artifactId>whisper</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>>
初始化翻譯Service
這里我們使用一個(gè)最基本的初始化方式。
該初始化的Service固定將所有內(nèi)容翻譯成中文。
事實(shí)上,你可以直接將這個(gè)類復(fù)制到你的項(xiàng)目中。
@Configuration
@EnableResourceServer
public class I18nTranslateConfig {
@Autowired
ApplicationContext applicationContext;
@Bean
public I18nTranslateService init() {
//this basic translator service always translate your data in Chinese language
return new I18nTranslateService(applicationContext);
}
}
現(xiàn)在,Whisper已經(jīng)準(zhǔn)備完畢!
嘗試一下!
Demo 1
將部門名稱翻譯成中文
首先我們寫一個(gè)Department類,像這樣:
@Data
public class Department {
// this is the department id , we will translate the department name by this id
@I18nMapping(i18nCode = "id")
private Long departmentId;
// this is the attribute we need to translate
@I18nMapping(i18nCode = "name")
private String departmentName;
private String description;
private Integer level;
}
假如我們希望把部門名稱翻譯成中文,只需要加兩個(gè)I18nMapping注解,分別用來指定待翻譯實(shí)體的id以及,要翻譯的字段。
在i18n_item表中,我們初始化一條中文翻譯:
insert into `i18n_item` values ( '1', 'zh_cn', 'name', '中文部門', '1', '0', '2018-08-23 21:41:24');
insert into `i18n_item` values ( '1', 'en', 'name', 'english department name', '1', '0', '2018-08-23 21:41:24');
現(xiàn)在讓我們看看效果!
在Controller中,添加一個(gè)示例的api,這個(gè)api中,我們返回一個(gè)名稱為english department name的部門:
@Controller
public class DemoController {
@RequestMapping(value = "/getOneDepartment")
@I18nTranslate
@ResponseBody
public Department getOneDepartment() {
Department department = new Department();
department.setDepartmentId(1L);
department.setDepartmentName("english department name");
department.setDescription("english description");
department.setLevel(0);
throw new RuntimeException("i18n exception test");
}
}
項(xiàng)目運(yùn)行后,調(diào)用該api,你會(huì)發(fā)現(xiàn)Whisper把departmentName字段翻譯成了中文!
{
"departmentId": 1,
"departmentName": "中文部門",
"description": "english description",
"level": 0
}
Demo 2
按指定的語言翻譯(比如用戶的當(dāng)前語言)
在Demo 1中,我們總是把任何東西翻譯成中文。
如果我們想按照api的調(diào)用者語言,返回相應(yīng)語言的翻譯怎么辦呢?
非常簡(jiǎn)單!
創(chuàng)建一個(gè)語言翻譯工具類,這個(gè)類將幫助我們決定按何種語言翻譯。
這個(gè)類需要實(shí)現(xiàn)TranslateToolService 接口。
下面是個(gè)簡(jiǎn)單的示意:
public class MyTranslateToolService implements TranslateToolService {
public String getCurrentLanguage() {
//some exist logic to get current user language
//for example from token or some other table
return someClass.getCurrentUserLanguage();
}
}
我們需要在I18nTranslateConfig中,使用新的構(gòu)造函數(shù)初始化I18nTranslateService。
該初始化指定了語言工具類為我們剛才新建的MyTranslateToolService。
@Configuration
@EnableResourceServer
public class I18nTranslateConfig {
@Autowired
ApplicationContext applicationContext;
@Bean
public I18nTranslateService init() {
return new I18nTranslateService(applicationContext,MyTranslateToolService);
}
}
現(xiàn)在,Whisper將按照MyTranslateToolService.getCurrentLanguage()方法的返回語言進(jìn)行翻譯!
Demo 3
一個(gè)國(guó)際化異常的例子
也許你希望將返回的錯(cuò)誤信息也按照當(dāng)前用戶的語言來翻譯。
使用Whisper框架做這件事情非常簡(jiǎn)單!
創(chuàng)建一個(gè)錯(cuò)誤信息DTO
假設(shè)我們將errorCode屬性作為i18n的翻譯ID。
我們希望將message屬性翻譯成不同語言。
只需要加兩個(gè)I18nMapping 的 annotation,非常簡(jiǎn)單。
@Builder
public class ExceptionDetail {
@I18nMapping(i18nCode = "message")
private String message;
@I18nMapping(i18nCode = "id")
private String errorCode;
}
創(chuàng)建一個(gè) ControllerAdvice來處理異常
@ControllerAdvice
public class ResourceAdvice {
@ExceptionHandler(RuntimeException.class)
@I18nTranslate
public ResponseEntity<ExceptionDetail> handleValidationException(RuntimeException e) {
ExceptionDetail detail = ExceptionDetail.builder().errorCode("e001").message("cccc").build();
return new ResponseEntity(detail, HttpStatus.BAD_REQUEST);
}
}
在 i18n_item 表中,初始化兩條翻譯項(xiàng)。
insert into `i18n_item` values ( 'e001', 'zh_cn', 'message', '中文報(bào)錯(cuò)', '1', '0', '2018-08-23 21:41:24');
insert into `i18n_item` values ( 'e001', 'en', 'message', 'english error message', '1', '0', '2018-08-23 21:41:24');
現(xiàn)在,你拋出的所有code為e001的報(bào)錯(cuò)都將被翻譯成指定的語言,修改DemoController自己試一試吧!
@Controller
public class DemoController {
@RequestMapping(value = "/getOneDepartment")
@I18nTranslate
@ResponseBody
public Department getOneDepartment() {
Department department = new Department();
department.setDepartmentId(1L);
department.setDepartmentName("english department name");
department.setDescription("english description");
department.setLevel(0);
throw new RuntimeException("i18n exception test");
}
}
如何創(chuàng)建i18n翻譯項(xiàng)
我們提供了一個(gè)簡(jiǎn)單的api,幫助你維護(hù)i18n翻譯項(xiàng),你可以通過這個(gè)api輕松地將你的項(xiàng)目與Whisper集成起來。
這里是一段樣例代碼:
@Inject
I18nTranslateService i18nTranslateService;
public Boolean createI18nItems(){
List<I18nTranslateItemDTO> i18nTranslateItemDTOS = new ArrayList<>();
i18nTranslateItemDTOS.add(I18nTranslateItemDTO.builder().i18nKey("1").code("name").language("en").name("department english name").build());
return i18nTranslateService.createOrUpdateI18nItems(i18nTranslateItemDTOS);
}
注意
我們使用i18nKey,i18nCode,language,作為聯(lián)合唯一索引。所以請(qǐng)保證所有的被指定為i18n id的屬性值全局唯一(@I18nMapping(i18nCode = "id"))。
最佳實(shí)踐是使用UUID作為i18n id,你可能需要為需要翻譯的表添加一列i18n_id,并用隨機(jī)的UUID填充。