Java uses Hibernate-Validator to verify API interface parameters

一、相关依赖

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.10.Final</version>
</dependency>

二、简单实例

Add a common interface information, and limit the incoming parameters to id not less than 10.

@Validated
@RestController
@RequestMapping("/example")
public class ExampleController {
    
    
    /**
     * @param id id数不能小于10 @RequestParam类型的参数需要在Controller上增加@Validated
     * @return
     */
    @RequestMapping(value = "/info",method = RequestMethod.GET)
    public String test(@Min(value = 10, message = "id最小只能是10") @RequestParam("id")
                                  Integer id){
    
    
        return "恭喜你拿到参数了";
    }
}

Add verification exception handling in global exception interception

@Slf4j
@ControllerAdvice
@Component
public class GlobalExceptionHandler {
    
    
    @ExceptionHandler
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String handle(ConstraintViolationException exception, HttpServletRequest request) {
    
    
        Set<ConstraintViolation<?>> violations = exception.getConstraintViolations();
        StringBuffer errorInfo = new StringBuffer();
        for (ConstraintViolation<?> item : violations) {
    
    
            /**打印验证不通过的信息*/
            errorInfo.append(item.getMessage());
            errorInfo.append(",");
        }
        log.error("{}接口参数验证失败,内容如下:{}",request.getRequestURI(),errorInfo.toString());
        return "您的请求失败,参数验证失败,失败信息如下:"+ errorInfo.toString();
    }
}

三、按照vo的验证

Add a vo entity information

@Data
public class ExampleVo {
    
    
    @NotBlank(message = "用户名不能为空")
    private String userName;

    @Range(min = 18,max = 60,message = "只能填报年龄在18~60岁的")
    private String age;
}

Add a POST request interface

 /**
  * @param vo 按照vo的验证
  * @return
  */
 @RequestMapping(value = "/info1",method = RequestMethod.POST)
 public String test1(@Valid  @RequestBody ExampleVo vo){
    
    
     return "success";
 }

Add the result of verification processing in the global exception interception

 @ResponseBody
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler(MethodArgumentNotValidException.class)
 public String handle(MethodArgumentNotValidException exception,HttpServletRequest request) {
    
    
     StringBuffer errorInfo=new StringBuffer();
     List<ObjectError> errors = exception.getBindingResult().getAllErrors();
     for(int i=0;i<errors.size();i++){
    
    
         errorInfo.append(errors.get(i).getDefaultMessage()+",");
     }
     log.error("{},接口参数验证失败:{}",request,errorInfo.toString());
     return "您的请求失败,参数验证失败,失败信息如下:"+errorInfo.toString();
 }

四、自定义注解

Custom annotation implementation, the attributes in vo must conform to the enumeration in the enumeration class.

4.1 Add custom annotations

@Target({
    
    ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumCheckValidator.class)
public @interface EnumCheck {
    
    
    /**
     * 是否必填 默认是必填的
     * @return
     */
    boolean required() default true;
    /**
     * 验证失败的消息
     * @return
     */
    String message() default "枚举的验证失败";
    /**
     * 分组的内容
     * @return
     */
    Class<?>[] groups() default {
    
    };

    /**
     * 错误验证的级别
     * @return
     */
    Class<? extends Payload>[] payload() default {
    
    };

    /**
     * 枚举的Class
     * @return
     */
    Class<? extends Enum<?>> enumClass();

    /**
     * 枚举中的验证方法
     * @return
     */
    String enumMethod() default "validation";
}

4.2 Annotated verification logic implementation class

public class EnumCheckValidator implements ConstraintValidator<EnumCheck,Object> {
    
    
    private EnumCheck enumCheck;

    @Override
    public void initialize(EnumCheck enumCheck) {
    
    
        this.enumCheck =enumCheck;
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
    
    
        // 注解表明为必选项 则不允许为空,否则可以为空
        if (value == null) {
    
    
            return this.enumCheck.required()?false:true;
        }
        //最终的返回结果
        Boolean result=Boolean.FALSE;
        // 获取 参数的数据类型
        Class<?> valueClass = value.getClass();
        try {
    
    
            Method method = this.enumCheck.enumClass().getMethod(this.enumCheck.enumMethod(), valueClass);
            result = (Boolean)method.invoke(this.enumCheck.enumClass(), value);
            result= result == null ? false : result;
            //所有异常需要在开发测试阶段发现完毕
        } catch (NoSuchMethodException e) {
    
    
            e.printStackTrace();
        } catch (IllegalAccessException e) {
    
    
            e.printStackTrace();
        } catch (InvocationTargetException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            return result;
        }
    }
}

4.3 Enumeration class

public enum  Sex{
    
    
    MAN("男",1),WOMAN("女",2);

    private String label;
    private Integer value;

    public String getLabel() {
    
    
        return label;
    }

    public void setLabel(String label) {
    
    
        this.label = label;
    }

    public Integer getValue() {
    
    
        return value;
    }

    public void setValue(Integer value) {
    
    
        this.value = value;
    }

    Sex(String label, int value) {
    
    
        this.label = label;
        this.value = value;
    }

    /**
     * 判断值是否满足枚举中的value
     * @param value
     * @return
     */
    public static boolean validation(Integer value){
    
    
        for(Sex s:Sex.values()){
    
    
            if(Objects.equals(s.getValue(),value)){
    
    
                return true;
            }
        }
        return false;
    }
}

4.4 use

@EnumCheck(message = "只能选男:1或女:2",enumClass = Sex.class)
private Integer sex;

五、分组验证

@Data
public class ExampleVo {
    
    
    @NotNull(message = "主键不允许为空",groups = ValidGroupA.class)
    private Integer id;

    @NotBlank(message = "用户名不能为空",groups = Default.class)
    private String userName;
    
    @Range(min = 18,max = 60,message = "只能填报年龄在18~60岁的",groups = Default.class)
    private String age;

    @EnumCheck(message = "只能选男:1或女:2",enumClass = Sex.class,groups = Default.class)
    private Integer sex;
}
@RequestMapping(value = "/info1",method = RequestMethod.POST)
 public String test1(@Validated({
    
    ValidGroupA.class,Default.class}) @RequestBody ExampleVo vo) {
    
    
     return "success";
 }



Guess you like

Origin blog.csdn.net/qq_27870421/article/details/130405899