SpringBoot 項目國際化

spring 項目國際化,前後端分離

一般一個項目稍微有可能的話國際化是基本需求,提前做好。
國際化嘛,首先是時間,其次就是語言了。我這邊就不談時間了,主要針對語言。

:防止亂碼國際化(數據庫和服務器)肯定統一UTF-8編碼。

項目後端提示國際化

1. LocalResolwer

利用spring對國際化的支持,使用內置的語言處理器。
重寫LocalResolwer,這個類其實已經得到了官方實現,但是我的項目是基於jwt的,所以決定自定義比較適合。
然後將自定義的處理器添加到WebMVCConfig中。

注意:通過獲取瀏覽器請求中自帶的header中的Accept-Language參數,也可以通過前後端約定自己設置的來。

2.國際化資源配置

IDEA環境下,在resources下新建Resource Bound文件,加上英文key和value。
在yml配置文件中,加上以下配置,注意空格對齊問題。

spring
  #國際化
   messages:
     basename: i18n/message
     encoding: UTF-8
     # 失效時間,-1永不
     cache-duration: -1

2.MessageSource

通過上面的配置,我們就可以拿到MessageSource,在代碼中可以通過@Autowired來注入使用。

3.統一定義返回類

像我的項目,所以的返回和異常都是從Result 繼承下去的,所以會形成一個很好的規範,同時在所有返回中只能存在資源文件中的key,在後面做替換。有助於下一步驟。

4.自定義過濾器

通過自定義過濾器I18NFilter,該類基礎自javax.servlet.Filter;
在I18NFilter中,對所以的返回進行過濾,將所有的key替換爲對應語言的國際化資源。

項目中的枚舉類型或者常量國際化

1、對枚舉類型的GET方法進行改造。
2、資源文件中將枚舉值進行配置。
public enum EnumSuccessOrError {
SUCCESS(0, “SUCCESS”),
ERROR(1, “ERROR”);

/**
 * 返回狀態碼
 */
private int statusCode;
/**
 * 返回狀態信息
 */
private String statusMsg;

EnumSuccessOrError(int statusCode, String statusMsg) {
    this.statusCode = statusCode;
    this.statusMsg = statusMsg;
}

private MessageSource messageSource;

public EnumSuccessOrError setMessageSource(MessageSource messageSource) {
    this.messageSource = messageSource;
    return this;
}

//通過靜態內部類的方式注入bean,並賦值到枚舉中
@Component
public static class ReportTypeServiceInjector {

    @Autowired
    private MessageSource messageSource;

    @PostConstruct
    public void postConstruct() {
        for (EnumSuccessOrError rt : EnumSet.allOf(EnumSuccessOrError.class))
            rt.setMessageSource(messageSource);
    }
}

/**
 * @return the statusCode
 */
public int getStatusCode() {
    return statusCode;
}

 /**
 * @return the statusMsg,根據語言環境返回國際化字符串
 */
public String getStatusMsg() {
    return messageSource.getMessage(statusMsg,null,statusMsg, LocaleContextHolder.getLocale());
}

數據庫部分

對於數據庫比如字典表這類表,只能做特殊處理,增加language字段,通過請求中的header語言進行特殊查詢。
也有看到用資源表,進行整個翻譯的這種說法,但是感覺明顯就很奇怪,比較這種表的情況屬於特例,其他的表一般不會存在這個問題,都是用戶自己存自己看。
還有那種實在是需要多個語言,而且業務需要的,比如存文章,就是非要多個語言,這種有看到多表或者多庫做處理的,具體也沒了解。基本上這種肯定就分佈式,不通地區訪問不同地區的服務器,NGINX就處理了,反而不需要這麼麻煩了。

代碼地址:github,過兩天放上去

/**

*國際化工具類

*@author Angel–守護天使

*@version v.0.1

*@date 2016年8月5日下午2:44:03

*/

@Component

publicclassLocaleMessageSourceService {

@Resource

private MessageSourcemessageSource;



/**

 *@param code:對應messages配置的key.

 *@return

 */

public StringgetMessage(Stringcode){

   returnthis.getMessage(code,new Object[]{});

}



public StringgetMessage(Stringcode,StringdefaultMessage){

   returnthis.getMessage(code,null,defaultMessage);

}



public StringgetMessage(Stringcode,StringdefaultMessage,Localelocale){

   returnthis.getMessage(code,null,defaultMessage,locale);

}



public StringgetMessage(Stringcode,Localelocale){

   returnthis.getMessage(code,null,"",locale);

}



/**

 *

 *@param code:對應messages配置的key.

 *@param args :數組參數.

 *@return

 */

public StringgetMessage(Stringcode,Object[]args){

   returnthis.getMessage(code,args,"");

}



public StringgetMessage(Stringcode,Object[]args,Localelocale){

   returnthis.getMessage(code,args,"",locale);

}







/**

 *

 *@param code:對應messages配置的key.

 *@param args :數組參數.

 *@param defaultMessage :沒有設置key的時候的默認值.

 *@return

 */

public StringgetMessage(Stringcode,Object[]args,StringdefaultMessage){

   //這裏使用比較方便的方法,不依賴request.

   Locale locale =LocaleContextHolder.getLocale();

   returnthis.getMessage(code,args,defaultMessage,locale);

}



/**

 *指定語言.

 *@param code

 *@param args

 *@param defaultMessage

 *@param locale

 *@return

 */

public StringgetMessage(Stringcode,Object[]args,StringdefaultMessage,Localelocale){

   returnmessageSource.getMessage(code,args,defaultMessage,locale);

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章