赞
踩
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
@Configuration
public class ValidationConfig {
@Bean
public LocalValidatorFactoryBean defaultValidator(MessageSource messageSource) {
LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
factoryBean.setValidationMessageSource(messageSource);
return factoryBean;
}
}
Spring Boot中针对Validation和国际化有两个自动配置类:
1、ValidationAutoConfiguration
2、MessageSourceAutoConfiguration
其中MessageSourceAutoConfiguration会自动实例化一个MessageSource实例,如下:
#国际化配置,basename可以用全限定类名,如下,也可以是i18n/message
spring.messages.basename=i18n.messages
spring.messages.encoding=UTF-8
注意:我们basename的配置为:spring.messages.basename=i18n.messages
因此在类路径下新建i18n
的文件夹即可,而不是i18n/messages
文件夹,文件夹内必须有一个文件名称为message.properties的属性文件,不然会有问题。多语言以messages_语言_国家.properties命名。
public class GlobalExceptionHandler { @ResponseBody @ExceptionHandler(MethodArgumentNotValidException.class) public ApiRespVO<?> handleException(MethodArgumentNotValidException e) { FieldError fieldError = e.getBindingResult().getFieldError(); // 校验注解名称 String code = fieldError.getCode(); // 校验字段名称 String field = fieldError.getField(); // 检验失败默认消息 String defaultMessage = fieldError.getDefaultMessage(); List<Object> args = Arrays.stream(Optional.ofNullable(fieldError.getArguments()).orElse(new Object[] {})) .filter(argument -> !(argument instanceof DefaultMessageSourceResolvable)) .map(Object::toString) .collect(Collectors.toList()); args.add(0, field); // 默认根据注解名称取,如果没有则取默认消息 String errorMsg = MessageUtils.getMessage(code, args.toArray(), LocaleContextHolder.getLocale(), StringUtils.EMPTY); if (StringUtils.isNotBlank(errorMsg)) { return ApiRespVO.failure(ErrorCode.INVALID_PARAM, errorMsg); } return ApiRespVO.failure(ErrorCode.INVALID_PARAM, defaultMessage); } }
备注:关于LocalContextHolder,每次web请求到来时,Spring中的
RequestContextFilter
会将Locale实例注入到LocalContextHolder。
public class MessageUtils {
private static MessageSource messageSource = WebApplicationContextHolder.getBean(MessageSource.class);
public static String getMessage(String code, Object[] args, Locale locale, String defaultValue) {
return messageSource.getMessage(code, args, defaultValue, locale);
}
public static String getMessage(String code, Object[] args, Locale locale) {
return messageSource.getMessage(code, args, locale);
}
}
public class ApiRespVO<T> { private static final String SUCCESS = "00000"; private static final String FAILURE = "99999"; private String code; private String message; private T data; public static <T> ApiRespVO<T> success() { return success(null); } public static <T> ApiRespVO<T> success(T data) { ApiRespVO<T> apiRespDTO = new ApiRespVO<>(); apiRespDTO.setCode(SUCCESS); apiRespDTO.setData(ObjectUtils.defaultIfNull(data, (T) new Object())); return apiRespDTO; } public static <T> ApiRespVO<T> failure(String code) { return failure(code, new Object[] {}); } public static <T> ApiRespVO<T> failure(String code, Object[] args) { String errorMsg = MessageUtils.getMessage(code, args, LocaleContextHolder.getLocale()); return failure(FAILURE, errorMsg); } public static <T> ApiRespVO<T> failure(String code, String message) { ApiRespVO<T> apiRespDTO = new ApiRespVO<>(); apiRespDTO.setCode(code); apiRespDTO.setMessage(message); return apiRespDTO; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } }
@RestController public class ValidationController { @Autowired private MessageSource messageSource; @RequestMapping("/validate") public ApiRespVO<?> hanldeRequest(@Validated @RequestBody UserReqDTO userDTO) { return ApiRespVO.success(); } @RequestMapping("/validate-list") public ApiRespVO<?> validateListParam(@Validated @RequestBody ChargeRuleReqDTO request) { return ApiRespVO.success(); } }
public class UserReqDTO { @NotNull private String username; @NotBlank @Length(min = 5,max = 8) private String password; @Size(max = 1) private String gender; @Positive private int age; @NotBlank @Pattern(regexp = "^\\d{11}$", message = "{Pattern.UserReqDTO.phone}") private String phone; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
public class ChargeRuleReqDTO { @NotBlank private String appId; @Valid private List<ChannelChargeInfo> chargeInfo; private static class ChannelChargeInfo { @NotBlank private String channelCode; @NotNull private BigDecimal channelCharge; public String getChannelCode() { return channelCode; } public void setChannelCode(String channelCode) { this.channelCode = channelCode; } public BigDecimal getChannelCharge() { return channelCharge; } public void setChannelCharge(BigDecimal channelCharge) { this.channelCharge = channelCharge; } } public String getAppId() { return appId; } public void setAppId(String appId) { this.appId = appId; } public List<ChannelChargeInfo> getChargeInfo() { return chargeInfo; } public void setChargeInfo(List<ChannelChargeInfo> chargeInfo) { this.chargeInfo = chargeInfo; } }
备注:如果请求参数DTO中实例变量为List集合对象,则要加上
@Valid注解
,否则校验不会生效。
messages.properties
NotNull=
NotBlank=
Length=
Positive=
Pattern.UserReqDTO.phone=
备注:文件内容为空即可
messages_en_US.properties
NotNull=[{0}] cannot be null
NotBlank=[{0}] cannot be blank
Length=[{0}] minimum length is {2},maximum length is {1}
Positive=[{0}] must be greater than 0
Pattern.UserReqDTO.phone=phone number format is invalid and must be digit. maximum length is 11
messages_zh_CN.properties
NotNull=[{0}]不能为空
NotBlank=[{0}]不能为空
Length=[{0}]最小长度为{2},最大长度为{1}
Positive=[{0}]必须大于
Pattern.UserReqDTO.phone=手机号格式不正确,必须为全数字,长度为11位
语言为中文:
语言为英文:
语言为中文:
语言为英文:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。