SpringBoot 之 国际化基本原理
1、国际化基本原理
- 第一步,获取语言标识 - 通过前端调用传入的参数
- 第二步,获取资源文件 - 通过语言标识获取对应资源文件
- 第三步,获取错误描述 - 从资源文件中根据错误编码获取错误描述,同时可支持参数替换描述中的占位符
- 第四步,何处拦截处理 - 在何处执行错误码翻译工作
2、SpringBoot实现国际化原理
在SpringBoot启动类中,@SpringBootApplication注解会引用@EnableAutoConfiguration注解。
- 第一步,获取语言标识,如下为几种实现方式:
- AcceptHeaderLocaleResolver:@EnableAutoConfiguration注解会自动加载配置WebMvcAutoConfiguration,该类中会直接配置AcceptHeaderLocaleResolver,
@Bean @ConditionalOnMissingBean @ConditionalOnProperty(prefix = "spring.mvc",name = {"locale"} ) public LocaleResolver localeResolver() { if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.WebMvcProperties.LocaleResolver.FIXED) { return new FixedLocaleResolver(this.mvcProperties.getLocale()); } else {
// 基于浏览器,从HttpServletRequest的Header中属性Accept-Language中获取语言标识 AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver(); localeResolver.setDefaultLocale(this.mvcProperties.getLocale()); return localeResolver; } }
-
- CookieLocaleResolver:基于Cookie,从cookie中获取语言标识
- SessionLocaleResolver:基于Session,从session中获取语言标识
-
- FixedLocaleResolver:返回固定的语言标识
- 第二步,获取资源文件,如下为几种方式:
- Yml配置:@EnableAutoConfiguration注解会自动加载配置MessageSourceAutoConfiguration,该类中会直接配置MessageSourceProperties,默认读取spring.message
Spring: messages: ## 资源文件路径 basename: i18n.messages ## 编码格式 encoding: UTF-8 ## 缓存有效期(单位:秒),-1:永久 cacheSeconds: -1 ## 当找不到当前语言的资源文件时,若为true,则默认找当前系统的语言对应的资源文件如messages_zh_CN.properties,如果为false即加载系统默认的如messages.properties文件。 fallbackToSystemLocale: true
- Yml配置:@EnableAutoConfiguration注解会自动加载配置MessageSourceAutoConfiguration,该类中会直接配置MessageSourceProperties,默认读取spring.message
- 自定义配置:在Configuration中自行配置方式,
@Configuration public class MessageSourceConfig { @Bean(name = "messageSource") public ResourceBundleMessageSource getMessageSource() throws Exception { ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource(); resourceBundleMessageSource.setDefaultEncoding("UTF-8");
// 指定了i18n文件的位置,这是个在i18n文件夹下的Resources Bundle文件集合,新建的时候在IDEA里面选择的是Resource Bundle类型,名字写的是messages。这个很重要,对应配置文件! resourceBundleMessageSource.setBasenames("i18n.messages"); return resourceBundleMessageSource; } }
如下为国际化资源文件:
【默认】messages.properties
【英文】messages_en_US.properties
【中文】messages_zh_CN.properties
- 第三步,获取错误描述,如下为实现方式:
代码当中使用MessageSource注入的方式:
@Autowired private MessageSource messageSource;
// 通过如下方式可以获取Locale
Locale locale = LocaleContextHolder.getLocale(); // 然后使用如下方式获取信息,同时args可以支持占位符替换 messageSource.getMessage(code, args, defaultMessage, locale); -
第四步,何处拦截处理,如下为实现方式:
- 实现接口HandlerExceptionResolver,比如在发生异常时返回统一ModelAndView
public class GenericResponseHandler implements HandlerExceptionResolver{ public ModelAndView resolveException(HttpServletRequest request,HttpServletReponse response,Object handler,Exception ex){ // 处理异常,并返回统一ModelAndView,同时,应用中Exception可以包一层,比如AppRtException,方便通过错误码获取错误描述
return new ModelAndView(....);
}
}
-
- ControllerAdvice下的ExceptionHandler
@ControllerAdvice public class GenericExceptionHandler { @Autowired private MessageSource messageSource;
/** * 全局处理业务的异常 * * @param ex * @return */ @ExceptionHandler(Exception.class) public ResponseEntity handleGenericException(Exception ex) {
// 同时,应用中Exception可以包一层,比如AppRtException,方便通过错误码获取错误描述
return ......
}
}
- ControllerAdvice下的ExceptionHandler
3、github代码链接地址:......