Validated

在这里插入图片描述

public enum ResultCode {
    /**操作成功**/
    RESULT_SUCCESS_CODE(200,"操作成功"),
    /**操作失败**/
    RESULT_ERROR_CODE(500,"操作失败");
    private final int code;
    private final String message;
    ResultCode(int code, String message){
        this.code = code;
        this.message = message;
    }
    public int getCode() { return code; }
    public String getMessage() { return message; }
}
public class ResultData<T> {
    /** 结果状态 ,具体状态码参见ResultData.java*/
    private int code;
    /**响应消息**/
    private String message;
    /**响应数据**/
    private T data;
    /**接口请求时间**/
    private long timestamp ;


    public ResultData (){
        this.timestamp = System.currentTimeMillis();
    }


    public static <T> ResultData<T> success(String message) {
        ResultData<T> resultData = new ResultData<>();
        resultData.setCode(ResultCode.RESULT_SUCCESS_CODE.getCode());
        resultData.setMessage(message);
        return resultData;
    }

    public static <T> ResultData<T> success() {
        ResultData<T> resultData = new ResultData<>();
        resultData.setCode(ResultCode.RESULT_SUCCESS_CODE.getCode());
        resultData.setMessage(ResultCode.RESULT_SUCCESS_CODE.getMessage());
        return resultData;
    }

    public static <T> ResultData<T> success(T data) {
        ResultData<T> resultData = new ResultData<>();
        resultData.setCode(ResultCode.RESULT_SUCCESS_CODE.getCode());
        resultData.setMessage(ResultCode.RESULT_SUCCESS_CODE.getMessage());
        resultData.setData(data);
        return resultData;
    }

    public static <T> ResultData<T> fail(String message) {
        ResultData<T> resultData = new ResultData<>();
        resultData.setCode(ResultCode.RESULT_ERROR_CODE.getCode());
        resultData.setMessage(message);
        return resultData;
    }

    public static <T> ResultData<T> fail(int code, String message) {
        ResultData<T> resultData = new ResultData<>();
        resultData.setCode(code);
        resultData.setMessage(message);
        return resultData;
    }

    public static <T>ResultData<T> fail() {
        ResultData<T> resultData = new ResultData<>();
        resultData.setCode(ResultCode.RESULT_ERROR_CODE.getCode());
        resultData.setMessage(ResultCode.RESULT_ERROR_CODE.getMessage());
        return resultData;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int 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;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }
}
@Data
public class User {
    @NotNull(groups = ValidationGroups.update.class, message = "id不能为空")
    @Null(groups = ValidationGroups.insert.class)
    private String id;

    @Length(min = 11,max = 11,message = "手机号格式不正确")
    private String phone;


    @NotBlank(message = "名字为必填项")
    private String name;

    @Email(message = "请填写正确的邮箱地址")
    private String email;

    @EnumValue(strValues = {"0","1"}, message="性别只能是0或者1")
    private String sex;

    @NotNull(message = "年龄不能为空")
    private Integer age;

    @Valid // 嵌套验证必须用@Valid
    private Dog dog;
}
@Data
public class Dog {
    @NotNull(message = "id不能为空")
    private Integer id;
    @NotBlank(message = "name不能为空")
    private String name;
}

自定义分组

public class ValidationGroups {
    public interface insert{};
    public interface update{};
}

自定义注解规则

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {EnumValueValidator.class})
public @interface EnumValue {

    // 默认错误消息
    String message() default "必须为指定值";

    String[] strValues() default {};

    int[] intValues() default {};

    // 分组
    Class<?>[] groups() default {};

    // 负载
    Class<? extends Payload>[] payload() default {};

    // 指定多个时使用
    @Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Documented
    @interface List {
        EnumValue[] value();
    }
}
public class EnumValueValidator implements ConstraintValidator<EnumValue, Object> {

    private String[] strValues;
    private int[] intValues;

    @Override
    public void initialize(EnumValue constraintAnnotation) {
        strValues = constraintAnnotation.strValues();
        intValues = constraintAnnotation.intValues();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (value instanceof String) {
            for (String s : strValues) {
                if (s.equals(value)) {
                    return true;
                }
            }
        } else if (value instanceof Integer) {
            for (int s : intValues) {
                if (s == ((Integer) value).intValue()) {
                    return true;
                }
            }
        }
        return false;
    }
}

异常增强类

@RestControllerAdvice
public class WebExceptionHandler extends RuntimeException{
    /** requestBody 实体类形式接受参数验证 **/
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResultData validationErrorHandler(MethodArgumentNotValidException ex) {
        String message = ex.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
        return ResultData.fail(message);
    }

    /** Form-data 实体类形式接受参数验证 **/
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public ResultData validationErrorHandler(BindException ex) {
        String message = ex.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
        return ResultData.fail(message);
    }

    /**  RequestParam 接受参数验证 **/
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public ResultData validationErrorHandler(ConstraintViolationException ex) {
        String message = ex.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());
        return ResultData.fail(message);
    }

    /** hibernate-valid实体类形式接受参数验证失败 **/
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResultData exceptionHandler(Exception ex) {
        return ResultData.fail(ex.getMessage());
    }
}

Controller

@RestController
//@Validated
public class ValidController {
    /** RequestBody **/
    @PostMapping("/test1")
    public String test1(@Validated @RequestBody User user){
        System.out.println(user);
        return "test1 valid success";
    }

    /** RequestBody **/
    @PostMapping("/test2")
    public String test2(@Valid @RequestBody User user){
        System.out.println(user);
        return "test1 valid success";
    }

    /** 单参数校验 **/
    @PostMapping("/test3")
    public String test3(@Email String email){
        return "email valid success";
    }

    @PostMapping("/add")
    public String add(@Validated({ValidationGroups.insert.class}) @RequestBody User user){
        return "add valid success";
    }
    @PostMapping("/update")
    public String update(@Validated({ValidationGroups.update.class}) @RequestBody User user){
        return "update valid success";
    }
}

@Validated和@Valid的区别

1.分组区别

@Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制
在这里插入图片描述
@Valid:没有分组的功能。
在这里插入图片描述

2. 注解地方

@Validated:可以用在类型、方法和方法参数上。

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {
	Class<?>[] value() default {};

}

@Valid:可以用在方法、构造函数、方法参数和成员属性(字段)上

@Target({ METHOD, FIELD, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
public @interface Valid {
}

嵌套验证

@Validated不能用于成员属性(字段)上,所有不能提供嵌套验证的功能。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jsxllht

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值