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);

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