2023年11月29日发(作者:)

SpringBoot@Validated拓展⾃定义参数校验

在Springboot中使⽤原⽣的@Validated进⾏参数校验时,只能对单独字段进⾏校验(例如字段长度、⼤⼩、不为空等),如果要对多字段进

⾏组合的校验,这时候需要⽤到⾃定义的参数校验。

今天以校验password1与password2是否相同为例,讲解如何⾃定义参数校验。

涉及代码⽬录结构如下:

controller层是测试⽤的接⼝,GlobalExceptionAdvice获取参数异常,dto为需要校验参数的对象,validates下的两个⽂件⽤于处理异常

参数的具体逻辑。

⾸先我们新建⼀个bean⽂件。

@Data

@PasswordEqual

@ControllerAdvice

public class GlobalExceptionAdvice {

@ExceptionHandler(MethodArgumentNotValidException.class)

@ResponseBody

@ResponseStatus(code = HttpStatus.BAD_REQUEST) // 400

返回响应码

public UnifyResponse handleBeanValidation(HttpServletRequest reg, MethodArgumentNotValidException e){

String reqUrl = reg.getRequestURI();

String method = reg.getMethod();

List<ObjectError> errors = e.getBindingResult().getAllErrors();

String message = formatAllErrorMessages(errors);

return new UnifyResponse(10001, message, method + " " + reqUrl);

}

//

拼接报错信息

private String formatAllErrorMessages(List<ObjectError> errors){

StringBuffer errorMsgs = new StringBuffer();

errors.forEach(error -> errorMsgs.append(error.getDefaultMessage()).append(";"));

return errorMsgs.toString();

}

}

PasswordEqual

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)

@Constraint(validatedBy = PasswordValidator.class)

public @interface PasswordEqual {

//

校验未通过时的返回信息

String message() default "passwords are not equal";

//

以下两⾏为固定模板

Class[] groups() default {};

Class extends Payload>[] payload() default {};

}

PasswordValidator

public class PasswordValidator implements ConstraintValidator<PasswordEqual, UserDTO> {

@Override

public boolean isValid(UserDTO userDTO, ConstraintValidatorContext constraintValidatorContext) {

String password1 = userDTO.getPassword1();

String password2 = userDTO.getPassword2();

// equals

这⾥只是做⽰例⽤,所以简单实⽤了进⾏对⽐,实际使⽤可以根据业务要求做更多拓展

boolean match = password1.equals(password2);

return match;

}

}

测试可以看到,如果传⼊参数password1与password2不相同,会返回我们⾃定义的响应内容。

这⾥的message内容是我们配置的默认信息,如果想修改message内容,可以在DTO层使⽤@PasswordEqual时,传⼊message内容,