使用Whisper框架快速為項(xiàng)目添加國(guó)際化支持

Wisper是一個(gè)輕量級(jí)I18n翻譯框架,簡(jiǎn)單易用,性能出色,并且擴(kuò)展簡(jiǎn)單。

讓我們看看如何開始使用Whisper!

假設(shè)你有一個(gè)基于Spring的項(xiàng)目,并且項(xiàng)目的dataSource已經(jīng)配置好。

可以在下面鏈接得到Whisper的樣例代碼

Whisper Demo

準(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填充。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 點(diǎn)我查看本文集的說明及目錄。 本項(xiàng)目相關(guān)內(nèi)容包括: 實(shí)現(xiàn)過程: CH7 創(chuàng)建在線商店 CH8 管理支付和訂單 CH...
    學(xué)以致用123閱讀 3,864評(píng)論 0 6
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,734評(píng)論 18 399
  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽明AI閱讀 16,210評(píng)論 3 119
  • 今天是沒聯(lián)系的第四天,還是我主動(dòng)發(fā)的消息,我知道你心情不好,可我想安慰你,可我應(yīng)該站在什么立場(chǎng)去安慰你呢?我再也不...
    擱淺淺淺閱讀 307評(píng)論 0 0
  • 浪費(fèi)時(shí)間就等于浪費(fèi)財(cái)富。對(duì)于經(jīng)商的人來說“時(shí)間就是金錢”一點(diǎn)都有沒錯(cuò)。賺錢靠的是珍惜時(shí)間,利用時(shí)間。天天早睡晚起做...
    股壇奇說閱讀 241評(píng)論 0 0

友情鏈接更多精彩內(nèi)容