普通国际化配置如下:
首先配置application.yml.如下图:
目录结构如下:
后台获取国际化的代码如下:
public static String getMessage(String mess, Object... args) {
//SpringBeanFactoryUtils是一个获取spring容器里的bean对象的工具类
MessageSource messageSource = SpringBeanFactoryUtils.getBean(MessageSource.class);
return messageSource.getMessage(mess, args, LocaleContextHolder.getLocale());
return mess;
}
//SpringBeanFactoryUtils类代码如下:
@Component
public final class SpringBeanFactoryUtils implements BeanFactoryPostProcessor{
/** Spring应用上下文环境 */
private static ConfigurableListableBeanFactory beanFactory;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{
SpringBeanFactoryUtils.beanFactory = beanFactory;
}
public static <T> T getBean(Class<T> clz) throws BeansException{
T result = (T) beanFactory.getBean(clz);
return result;
}
}
还要自定义一个Locale
@Component
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
String locale = request.getParameter("locale");
Locale defaultLocale = Locale.getDefault();//使用默认配置
if(TextUtils.isNullOrEmptyTrim(locale)){ //如果前端切换语言那locale就有值
String[] split = locale.split("_");
defaultLocale = new Locale(split[0],split[1]); // new Locale(语言,国家)
} //自己写cookie记住上次选择的语言
return defaultLocale;
}
/**
* 默认解析器 其中locale表示默认语言
*/
@Bean
public LocaleResolver localeResolver() {
return new MyLocaleResolver();
}
}
--------------------------------------普通的页面国际化已OK,接下来引入validator的国际化
springboot默认是将国际化文件命名为ValidationMessages例如ValidationMessages_zh_CN.properties.
ValidationMessages_zh_TW.properties.国际化配置文件必须放在classpath的根目录下,即src/java/resources的根目录下。
若要自定义文件位置或名称则需要重写WebMvcConfigurerAdapter 的 getValidator 方法,但WebMvcConfigurerAdapter在springboot2中已经废弃了,可以改为使用WebMvcConfigurationSupport,这里就是我踩的坑
在方法的参数上用@Valid注解,创建校验参数的类
AskForLeaveForm类如下:
@NotBlank(message ="{LeaveType}{CannotBeEmpty}")
private String leaveType;
@NotNull(message = "{JobAgent}{CannotBeEmpty}")
private Long agentPerson;
@DecimalMin (value = "0.5", message = "{applyForDay.not.null}{value}")
@NotNull(message = "{applyForDay}{CannotBeEmpty}")
private Double vDay;
private String vPhoto;
@NotBlank(message = "{startDate}{CannotBeEmpty}")
private String startDate;
@NotNull(message = "{startDate}{TmeQuantum}{CannotBeEmpty}")
private Integer startTimeInterval;
@NotBlank(message = "{endDate}{CannotBeEmpty}")
private String endDate;
@NotNull(message = "{endDate}{TmeQuantum}{CannotBeEmpty}")
private Integer endTimeInterval;
注意:Integer和Double类型不能用@NotBlank注解.要用@NotNull,如果用的注解不对.就不会是触发BindException异常.
如下是ControllerAdvice类 (统一异常处理)
//捕获Exception异常
@ExceptionHandler(value = BindException.class)
public Object jsonErrorHandler(HttpServletRequest request, BindException e) throws Exception {
List<FieldError> list = e.getFieldErrors();
String fieldErrorMsg = list.stream().map(FieldError::getDefaultMessage).collect(Collectors.joining(","));
if(isAjax(request)){ //如果是ajax方法请求
BaseModel model=new BaseModel(); //这是自定义对象.可换
model.setCode(BaseModel.ERROR);
model.setMessage(fieldErrorMsg);
return model;
}else{ //如果是前端页面请求
ModelAndView model = new ModelAndView();
model.addObject("errorMessage", fieldErrorMsg);
model.setViewName("jsp/common/systemBusy");
return model;
}
}
注意:FieldError中的getDefaultMessage方法已经实现了读取国际化,不需要手动读取国际化的值
下面测试 如下图:
在AskForLeaveForm参数校验类中的
@NotNull(message = "{JobAgent}{CannotBeEmpty}")
private Long agentPerson;