The Bean Validation reference implementation. - Hibernate Validator
1. 引入
1.1. old
<!--jsr 303-->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<!-- hibernate validator-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.0.Final</version>
</dependency>
1.2. 2.3.0 后
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
2. 注解
2.1. @Valid @Validated
区别 | @Valid | @Validated |
提供者 | JSR-303 | Spring |
分组 | 不支持 | 支持 |
标注位置 | 方法方法参数构造函数成员属性泛型 | 类型方法方法参数 |
嵌套校验 | 支持 | 不支持 |
2.2. @Null
2.3. @NotNull
2.4. @Email
2.5. 数字
- @Min(value)
- @Max(value)
- @DecimalMin(value)
- @DecimalMax(value)
- @Digits (integer, fraction)
2.6. 字符串
- @Length(min=, max=)
- @NotEmpty
- @NotBlank
2.7. 日期
- @Past
- @Future
2.8. boolean Boolean
@AssertTrue
@AssertFalse
2.9. @Range(min=, max=)
数字 或字符串
2.10. @Size(max, min)
CharSequence (length of character sequence is evaluated)
Collection (collection size is evaluated)
Map (map size is evaluated)
Array (array length is evaluated)
2.11. @Pattern(regexp = )
3. 实体
@Data
public class ValidTemp {
/**
* 登录名
*/
@NotNull
@Size(min = 6, max = 11)
private String loginName;
/**
* 用户名称
*/
@NotEmpty
private String userName;
/**
* 登录密码
*/
@ValidPassword
private String password;
private String email;
}
4. controller
@RestController
@RequiredArgsConstructor
@RequestMapping("/valid")
public class ValidController {
/**
* post 请求 校验的演示
*
* @param validTemp
* @return
*/
@PostMapping("/post")
public ValidTemp ValidPost(@Validated @RequestBody ValidTemp validTemp) {
validTemp.setEmail("dddddd");
return validTemp;
}
@GetMapping("/getVaild")
public ValidTemp selectUserInfo(@RequestParam("s") @Size(max = 3, message = "长度超过3") String s) {
ValidTemp validTemp = new ValidTemp();
validTemp.setEmail(s);
return validTemp;
}
}
5. BindingResult
@PostMapping("/ValidPostOld")
public ValidTemp ValidPostOld(@Valid @RequestBody ValidTemp validTemp, BindingResult bindingResult) {
if (bindingResult.hasErrors()){
List<ObjectError> allErrors = bindingResult.getAllErrors();
}
validTemp.setEmail("dddddd");
return validTemp;
}
6. 全局参数校验失败返回
@RestControllerAdvice
@Slf4j
@RequiredArgsConstructor
public class ExceptionControllerAdvice {
private final ResultUtils resultUtils;
private final ObjectMapper objectMapper;
/**
* 参数统一异常处理
*对方法参数校验异常处理方法(前端提交的方式为json格式出现异常时会被该异常类处理)
*json格式提交时,spring会采用json数据的数据转换器进行处理(进行参数校验时错误是抛出MethodArgumentNotValidException异常)
* @param e MethodArgumentNotValidException
* @return {@link ResultVO}
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultVO<Object> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e,HttpServletRequest request) throws JsonProcessingException {
BindingResult bindingResult = e.getBindingResult();
List<String> collect = bindingResult.getFieldErrors().stream().map(f -> (
String.join(" : ", f.getField(), f.getDefaultMessage())
)).collect(Collectors.toList());
log.warn("url[{}], 请求方式[{}]",request.getRequestURI(),request.getMethod());
log.warn("参数[{}]", objectMapper.writeValueAsString(bindingResult.getTarget()));
log.warn("参数校验失败[{}]",collect.toString());
return resultUtils.resultWarren(ResultEnumsWarren.PARAMETER_WARREN, collect);
}
}
7. 自定义注解
@Documented
@Constraint(validatedBy = PasswordConstraintValidator.class)
@Target({ TYPE, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
public @interface ValidPassword {
String message() default " 密码不正确";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@RequiredArgsConstructor
public class PasswordConstraintValidator implements ConstraintValidator<ValidPassword, String> {
private final SpringMessageResolver messageResolver;
@Override
public void initialize(final ValidPassword constraintAnnotation) {
}
@Override
public boolean isValid(final String password, final ConstraintValidatorContext context) {
val validator = new PasswordValidator(messageResolver, Arrays.asList(
// 长度规则:8 - 30 位
new LengthRule(8, 30),
// 至少有一个大写字母
new CharacterRule(EnglishCharacterData.UpperCase, 1),
// 至少有一个小写字母
new CharacterRule(EnglishCharacterData.LowerCase, 1),
// 至少有一个数字
new CharacterRule(EnglishCharacterData.Digit, 1),
// 至少有一个特殊字符
new CharacterRule(EnglishCharacterData.Special, 1),
// 不允许连续 3 个字母,按字母表顺序
// alphabetical is of the form 'abcde', numerical is '34567', qwery is 'asdfg'
// the false parameter indicates that wrapped sequences are allowed; e.g. 'xyzabc'
new IllegalSequenceRule(EnglishSequenceData.Alphabetical, 5, false),
// 不允许 3 个连续数字
new IllegalSequenceRule(EnglishSequenceData.Numerical, 5, false),
// 不允许 QWERTY 键盘上的三个连续相邻的按键所代表的字符
new IllegalSequenceRule(EnglishSequenceData.USQwerty, 5, false),
// 不允许包含空格
new WhitespaceRule()));
RuleResult result = validator.validate(new PasswordData(password));
if (result.isValid()) {
return true;
}
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(String.join(",", validator.getMessages(result)))
.addConstraintViolation();
return false;
}
}
8. 国际化
对应的内容可以在对应框架的官网查找
@Bean
public LocalValidatorFactoryBean getValidator() {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource);
return bean;
}