[[i18n]]
= 国际化 / I18n


`国际化的相关类位于net.parim.spark.i18n包下`

==  I18nConfiguration
[source,java]
----
package net.parim.spark.i18n.config;

import java.util.Locale;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

/**
 * 国际化相关配置
 * 
 * @author jiawei
 *
 */
@Configuration
public class I18nConfiguration extends WebMvcConfigurerAdapter   {

	/**
	 * 使用cookie区域解析器
	 * 
	 * @return
	 */
	@Bean
	public LocaleResolver localeResolver() {
		CookieLocaleResolver slr = new CookieLocaleResolver();
		// 设置默认区域,
		slr.setDefaultLocale(Locale.CHINA);
		slr.setCookieMaxAge(0);// 设置cookie有效期.
		return slr;
	}

	/**
	 * 使用参数修改用户的区域,默认为：locale,中文参数值为（zh_CN）,英文（en_US）
	 * @return
	 */
	@Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
         LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
         // 设置请求地址的参数,默认为：locale
         lci.setParamName(LocaleChangeInterceptor.DEFAULT_PARAM_NAME);
         return lci;
   }

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(localeChangeInterceptor());
	}
}
----

== application.properties
当前工程采用多模块的开发方式，为了使国际化文件按照模块进行分离，需要配置spring.messages.basename属性，指定国际化文件的位置和名称前缀。应遵循下面的约定。

* 国际化文件应位于resources目录下
* 一级包名为i18n,二级包名为模块名
* 国际化文件名必须以message开头
* 至少应包含message.properties,message_zh_CN.properties
[NOTE]
需要注意不同国家配置文件的文件名是下划线，不是中横线

image::images/i18n-config.png[]
* 配置实例
[source,java]
----
#指定message的basename，多个以逗号分隔，如果不加包名的话，默认从classpath路径开始
spring.messages.basename=i18n/common/message,i18n/system/message
----

== LocaleMessageSourceService
[source,java]
----
package net.parim.spark.i18n;

import java.util.Locale;

import javax.annotation.Resource;

import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;

/**
 * 自定义国际化获取工具类
 * 封装 MessageSource ，隐藏获取Locale动作，简化调用方法。
 *
 */
@Component
public class LocaleMessageSourceService {
   
    @Resource
    private MessageSource messageSource;
   
    /**
     * @param code ：对应messages配置的key.
     * @return
     */
    public String getMessage(String code){
       return getMessage(code,null,null);
    }
    /**
     * @param code ：对应messages配置的key.
     * @return
     */
    public String getMessage(String code,String defaultMessage){
    	return getMessage(code,null,defaultMessage);
    }
   
    /**
     *
     * @param code ：对应messages配置的key.
     * @param args : 数组参数.
     * @return
     */
    public String getMessage(String code,Object[] args){
       return getMessage(code, args,"");
    }
   
 
    /**
     *
     * @param code ：对应messages配置的key.
     * @param args : 数组参数.
     * @param defaultMessage : 没有设置key的时候的默认值.
     * @return
     */
    public String getMessage(String code,Object[] args,String defaultMessage){
       //这里使用比较方便的方法，不依赖request.
       Locale locale = LocaleContextHolder.getLocale();
       return messageSource.getMessage(code, args, defaultMessage, locale);
    }
   
}

----
使用
```
system.lang=中文
system.name=xx培训
system.welcome=欢迎登录{0}系统
```
[source,java]
----
@Controller
public class I18nTestController {

	@Autowired
	private LocaleMessageSourceService messageSource;

	@ResponseBody
	@RequestMapping("i18n")
	public Map<String, Object> i18n() {
		Map<String, Object> result = new HashMap<>();
		result.put("system.lang", messageSource.getMessage("system.lang"));
		result.put("system.name", messageSource.getMessage("system.name"));
		result.put("system.welcome", messageSource.getMessage("system.welcome",new String[]{messageSource.getMessage("system.name")}));
		return result;
	}
}
----

输出结果为：
```
{
    "system.name":"xx培训",
    "system.welcome":"欢迎登录xx培训系统",
    "system.lang":"中文"
}
```