Spring自带国际化方案
向容器中注册一个MessageSource类型的bean
bean类型必须是MessageSource类型
bean名称必须为messageSource
ResourceBundleMessageSource和ReloadableResourceBundleMessageSource,使用哪个都可以,具体参考加载国际化资源文件
@Configuration
public class MessageSourceConfig {
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
// 指定国际化资源文件位置
messageSource.setBasename("classpath:i18n/messages");
return messageSource;
}
}
资源文件位置结构
自定义获取消息工具类
自定义是为了能方便定义
Locale
(自动识别本地系统语言环境、配置文件设置固定语言环境、识别浏览器请求时语言环境)
public class MessageUtils {
private static final MessageSource MESSAGESOURCE = SpringContextHolder.getBean(MessageSource.class);
private static final MessageSourceConfig MESSAGESOURCECONFIG = SpringContextHolder.getBean(MessageSourceConfig.class);
/**
* 语言环境顺序
* 1.获取浏览器请求语言环境
* 2.获取配置文件语言环境
* 3.获取本地语言环境
*
* @param code code 消息键
* @param args 参数
* @return message
*/
public static String message(String code, Object... args) {
Locale locale;
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
// 前端请求语言环境
locale = attributes.getRequest().getLocale();
} else if (StringUtils.isNotBlank(MESSAGESOURCECONFIG.getParam())) {
// 配置文件语言环境
String[] params = MESSAGESOURCECONFIG.getParam().split("_");
String language = params[0];
String country = params[1];
locale = new Locale(language, country);
} else {
// 本地系统语言环境
locale = LocaleContextHolder.getLocale();
}
return MESSAGESOURCE.getMessage(code, args, locale);
}
}
工具类使用
MessageUtils.message("message.clientMessage.msg0002")
validation校验相关注解的国际化方案
如果想在校验相关注解实现国家化需要特殊处理,需要在当前服务定义配置文件向容器注册一个LocalValidatorFactoryBean类型的bean。
- 方式1:自动识别本地系统语言环境
/**
* 定义配置文件,注册一个LocalValidatorFactoryBean类型的bean
*/
@Configuration
public class ValidationMessageConfig implements WebMvcConfigurer {
@Resource
MessageSource messageSource;
@Override
@Bean
public LocalValidatorFactoryBean getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource);
return validator;
}
}
/**
* 实体类注解以类似于占位符式的形式
*/
@Data
public class GoodsBatch {
@NotNull(message = "{upms.validation.msg0001}")
private Integer id;
@NotNull(message = "{upms.validation.msg0002}")
private SpecSelect specSelect;
}
- 方式2:识别配置自定义语言环境
/**
* 识别配置自定义语言环境,需要重写MessageInterpolator拦截器
*/
@Configuration
public class ValidationMessageConfig implements WebMvcConfigurer {
@Override
@Bean
public LocalValidatorFactoryBean getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setMessageInterpolator(new MessageInterpolator());
return validator;
}
private static class MessageInterpolator extends ResourceBundleMessageInterpolator {
@Override
public String interpolate(String message, Context context, Locale locale) {
String validationMessage;
// 排除注解不填写message时validation自带国际化和填写了message的消息
if (!message.contains("javax.validation.constraints.") && message.contains(".validation.")) {
validationMessage = MessageUtils.message(message);
} else {
validationMessage = message;
}
return super.interpolate(validationMessage, context, locale);
}
}
}
/**
* 实体类注解这种形式ctrl+点击可以直接进入声明的国际化资源文件里
*/
@Data
public class GoodsBatch {
@NotNull(message = "upms.validation.msg0001")
private Integer id;
@NotNull(message = "upms.validation.msg0002")
private SpecSelect specSelect;
}