i18n国际化-springboot整合
简介
i18n(其来源是英文单词internationalization的首末字符i和n,18为中间的字符数)是“国际化”的简称。在资讯领域,国际化(i18n)指让产品(出版物,软件,硬件等)无需做大的改变就能够适应不同的语言和地区的需要。对程序来说,在不修改内部代码的情况下,能根据不同语言及地区显示相应的界面。在全球化的时代,国际化尤为重要,因为产品的潜在用户可能来自世界的各个角落。通常与i18n相关的还有L10n(“本地化”的简称)。。
springboot项目整合国际化
application.yml文件配置
# Spring配置
spring:
# 资源信息
messages:
# 国际化资源文件路径
basename: i18n/messages
encoding: utf-8
ps: basename配置为项目的多语言资源文件地址,如下图所示,多语言文件命名规则为:资源名称_语言_国家/地区
工具类
public class MessageUtils
{
/**
* 根据消息键和参数 获取消息 委托给spring messageSource
* 适用场景,系统全局语言
* @param code 消息键
* @param args 参数 用于填充消息中的参数(消息中的参数看起来像“{0}”,“{1,date}”,“{2,time}”)
* @return 获取国际化翻译值
*/
public static String message(String code, Object... args)
{
MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
}
/**
* 根据消息键和参数 获取消息 委托给spring messageSource 指定特定语言
* @param code 消息键
* @param locale 使用的语言eg:ENGLISH
* @param args 参数
* @return 获取国际化翻译值
*/
public static String message(String code, Locale locale, Object... args)
{
MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
return messageSource.getMessage(code, args, locale);
}
}
/**
* spring工具类 方便在非spring管理环境中获取bean
*
* @author ruoyi
*/
@Component
public final class SpringUtils implements BeanFactoryPostProcessor
{
/** Spring应用上下文环境 */
private static ConfigurableListableBeanFactory beanFactory;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{
SpringUtils.beanFactory = beanFactory;
}
/**
* 获取对象
*
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws org.springframework.beans.BeansException
*
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException
{
return (T) beanFactory.getBean(name);
}
/**
* 获取类型为requiredType的对象
*
* @param clz
* @return
* @throws org.springframework.beans.BeansException
*
*/
public static <T> T getBean(Class<T> clz) throws BeansException
{
T result = (T) beanFactory.getBean(clz);
return result;
}
/**
* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
国际化拦截器配置
@Configuration
public class I18nConfig {
@Bean
public LocaleResolver localeResolver()
{
SessionLocaleResolver slr = new SessionLocaleResolver();
// 默认语言
slr.setDefaultLocale(Locale.CHINA);
return slr;
}
/**
* header拦截器 其中lang表示切换语言的参数名
* 在spring boot2.0 之后 通过继承WebMvcConfigurer类 就可以完成拦截
* 在这里他直接返回了一个覆写了addInterceptors方法的WebMvcConfigurer匿名对象
* 以十分简洁的方式达成了他的目的
*/
@Bean
public WebMvcConfigurer i18nInterceptor() {
return new WebMvcConfigurer() {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//默认拦截器:请求国际化参数为?lang=en_us
//LocaleChangeInterceptor i18nInterceptor = new LocaleChangeInterceptor();
//自定义header拦截器,请求参数在header中添加lang的键值
LocaleChangeInterceptor i18nInterceptor = new HeaderLocaleChangeInterceptor();
i18nInterceptor.setParamName("lang");
registry.addInterceptor(i18nInterceptor).addPathPatterns("/**");
}
};
}
}
自定义拦截器
/**
* i18n拦截器:从请求头获取国际化参数
* @author Leoz
* @date 2021/9/29 17:07
*/
public class HeaderLocaleChangeInterceptor extends LocaleChangeInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException {
//从请求头获取国际化参数
String newLocale = request.getHeader(this.getParamName());
if (newLocale != null && this.checkHttpMethod(request.getMethod())) {
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
if (localeResolver == null) {
throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?");
}
try {
localeResolver.setLocale(request, response, this.parseLocaleValue(newLocale));
} catch (IllegalArgumentException var7) {
if (!this.isIgnoreInvalidLocale()) {
throw var7;
}
this.logger.debug("Ignoring invalid locale value [" + newLocale + "]: " + var7.getMessage());
}
}
return true;
}
private boolean checkHttpMethod(String currentMethod) {
String[] configuredMethods = this.getHttpMethods();
if (ObjectUtils.isEmpty(configuredMethods)) {
return true;
} else {
String[] var3 = configuredMethods;
int var4 = configuredMethods.length;
for(int var5 = 0; var5 < var4; ++var5) {
String configuredMethod = var3[var5];
if (configuredMethod.equalsIgnoreCase(currentMethod)) {
return true;
}
}
return false;
}
}
}
测试
@RestController
class Test {
@RequestMapping("/test")
public String test() {
String message = MessageUtils.message("test");
return message;
}
}
在messages.properties中添加内容:test=測試
在messages_en_US.properties中添加内容:test=test
postman请求结果
这里国际化整合完成
注意:如果没有找到对应的语言将会采用默认语言展示,这里是messages.properties
更多语言格式参考 java.util.Locale类
/** Useful constant for language.
*/
static public final Locale ENGLISH = createConstant("en", "");
/** Useful constant for language.
*/
static public final Locale FRENCH = createConstant("fr", "");
/** Useful constant for language.
*/
static public final Locale GERMAN = createConstant("de", "");
/** Useful constant for language.
*/
static public final Locale ITALIAN = createConstant("it", "");
/** Useful constant for language.
*/
static public final Locale JAPANESE = createConstant("ja", "");
/** Useful constant for language.
*/
static public final Locale KOREAN = createConstant("ko", "");
/** Useful constant for language.
*/
static public final Locale CHINESE = createConstant("zh", "");
/** Useful constant for language.
*/
static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");
/** Useful constant for language.
*/
static public final Locale TRADITIONAL_CHINESE = createConstant("zh", "TW");
/** Useful constant for country.
*/
static public final Locale FRANCE = createConstant("fr", "FR");
/** Useful constant for country.
*/
static public final Locale GERMANY = createConstant("de", "DE");
/** Useful constant for country.
*/
static public final Locale ITALY = createConstant("it", "IT");
/** Useful constant for country.
*/
static public final Locale JAPAN = createConstant("ja", "JP");
/** Useful constant for country.
*/
static public final Locale KOREA = createConstant("ko", "KR");
/** Useful constant for country.
*/
static public final Locale CHINA = SIMPLIFIED_CHINESE;
/** Useful constant for country.
*/
static public final Locale PRC = SIMPLIFIED_CHINESE;
/** Useful constant for country.
*/
static public final Locale TAIWAN = TRADITIONAL_CHINESE;
/** Useful constant for country.
*/
static public final Locale UK = createConstant("en", "GB");
/** Useful constant for country.
*/
static public final Locale US = createConstant("en", "US");
/** Useful constant for country.
*/
static public final Locale CANADA = createConstant("en", "CA");
/** Useful constant for country.
*/
static public final Locale CANADA_FRENCH = createConstant("fr", "CA");