• 数据校验JSR303入门实践


    数据校验JSR303入门实践

    1 基础校验

    1.引入pom

    javax.validation
    validation-api
    2.0.1.Final

    2.在Controller入口处增加@Valid
    3.在实体属性上增加校验规则注解 如@NotBlank和 @URL(是hibernate提供的注解,实现了JSR303规范)
    3.1使用@URL 需要引入hibernate pom

    org.hibernate.validator
    hibernate-validator
    6.2.0.Final

    2 分组校验

    1.在Controller入口处替换@Valid为@Validated 并指定分组接口,如@Validated(value = UpdateValidateGroup.class)
    2.在实体属性校验规则注解中设置groups参数,指定为分组接口类,如
    @NotNull(groups = {UpdateValidateGroup.class}) 更新操作不能为null
    @Null(groups = {AddValidateGroup.class}) 新增操作必须为null
    3.测试生效

    3 自定义校验

    1.创建校验组件接口ListValue
    2.创建自定义校验器 ListValueValidatorForInteger
    3.在组件接口中指定自定义校验器,如@Constraint(validatedBy = {ListValueValidatorForInteger.class})
    4.注解到实体属性上 如 @ListValue(value = {0, 1}, message = “仅支持0和1”, groups = AddValidateGroup.class)
    5.测试生效

    4 上code

    4.1 导入POM

            <dependency>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
                <version>2.0.1.Final</version>
            </dependency>
            <dependency>
                <groupId>org.hibernate.validator</groupId>
                <artifactId>hibernate-validator</artifactId>
                <version>6.2.0.Final</version>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4.2 定义实体类

    import com.iosc.bcmls.bcmlsps1.validate.ListValue;
    import com.iosc.bcmls.bcmlsps1.validate.group.AddValidateGroup;
    import com.iosc.bcmls.bcmlsps1.validate.group.UpdateValidateGroup;
    import lombok.Data;
    import org.hibernate.validator.constraints.URL;
    
    import javax.validation.constraints.Min;
    import javax.validation.constraints.NotBlank;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Null;
    import javax.validation.constraints.Pattern;
    import java.io.Serializable;
    
    @Data
    public class BrandEntity implements Serializable {
        private static final long serialVersionUID = 1L;
    
        @NotNull(groups = {UpdateValidateGroup.class})
        @Null(groups = {AddValidateGroup.class})
        private Long brandId;
    
        /**
         * 约束name不能为null,且至少有一个非空字符
         */
        @NotBlank(message = "品牌名必须提交", groups = {AddValidateGroup.class})
        private String name;
    
        /**
         * URL是hibernate提供的注解,实现了JSR303规范。约束如果logo不为null的话,必须符合url格式
         */
        @NotBlank(message = "logo不能为空")
        @URL(message = "logo格式不符")
        private String logo;
    
        private String desc;
        /**
         * 自定义校验组件 ListValue
         *
         * @Pattern(regexp = "[0-1]")
         * pattern不支持Integer
         */
        @ListValue(value = {0, 1}, message = "仅支持0和1", groups = AddValidateGroup.class)
        private Integer showStatus;
    
        /**
         * 使用正则表达式约束字段
         */
        @Pattern(regexp = "^[a-zA-Z]$", message = "首字母必须是一个字母")
        private String firstLetter;
    
        @Min(value = 0, message = "排序字段必须大于等于0")
        private Integer sort;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    4.3 controller入口类

    import com.alibaba.cola.dto.SingleResponse;
    import com.iosc.bcmls.bcmlsps1.domain.BrandEntity;
    import com.iosc.bcmls.bcmlsps1.validate.group.AddValidateGroup;
    import com.iosc.bcmls.bcmlsps1.validate.group.UpdateValidateGroup;
    import org.springframework.validation.annotation.Validated;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.validation.Valid;
    
    @RestController
    @RequestMapping("/validate")
    public class Jsr303Controller {
    
        /**
         * 【基础校验】
         * 1.引入pom
         *         
         *             javax.validation
         *             validation-api
         *             2.0.1.Final
         *         
         * 2.在Controller入口处增加@Valid
         * 3.在实体属性上增加校验规则注解 如@NotBlank和 @URL(是hibernate提供的注解,实现了JSR303规范)
         * 3.1使用@URL 需要引入hibernate pom
         *        
         *             org.hibernate.validator
         *             hibernate-validator
         *             6.2.0.Final
         *         
         *
         * 【分组校验】
         * 1.在Controller入口处替换@Valid为@Validated 并指定分组接口,如@Validated(value = UpdateValidateGroup.class)
         * 2.在实体属性校验规则注解中设置groups参数,指定为分组接口类,如
         *     @NotNull(groups = {UpdateValidateGroup.class})   更新操作不能为null
         *     @Null(groups = {AddValidateGroup.class})         新增操作必须为null
         * 3.测试生效
         *
         * 【自定义校验组件】
         * 1.创建校验组件接口ListValue
         * 2.创建自定义校验器 ListValueValidatorForInteger
         * 3.在组件接口中指定自定义校验器,如@Constraint(validatedBy = {ListValueValidatorForInteger.class})
         * 4.注解到实体属性上 如 @ListValue(value = {0, 1}, message = "仅支持0和1", groups = AddValidateGroup.class)
         * 5.测试生效
         *
         *
         * @param brandEntity
         * @return
         */
        @PostMapping("base")
        public SingleResponse base(@RequestBody @Valid BrandEntity brandEntity) {
            return SingleResponse.of("base validate ok!");
        }
    
        @PostMapping("update")
        public SingleResponse update(@RequestBody @Validated(value = UpdateValidateGroup.class) BrandEntity brandEntity) {
            return SingleResponse.of("update validate ok!");
        }
    
    
        @PostMapping("add")
        public SingleResponse add(@RequestBody @Validated(value = AddValidateGroup.class) BrandEntity brandEntity) {
            return SingleResponse.of("add validate ok!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    4.4 全局异常处理

    import com.alibaba.cola.dto.Response;
    import com.alibaba.cola.dto.SingleResponse;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.validation.BindingResult;
    import org.springframework.validation.FieldError;
    import org.springframework.web.bind.MethodArgumentNotValidException;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    import org.springframework.web.context.request.WebRequest;
    import org.springframework.web.util.NestedServletException;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * description: 全局异常处理
     */
    @Slf4j
    @RestControllerAdvice
    public class GlobalExceptionHandler {
    
        /**
         * 参数校验异常
         *
         * @param exception
         * @return
         */
        @ExceptionHandler(MethodArgumentNotValidException.class)
        public Response handleArgumentException(MethodArgumentNotValidException exception) {
            BindingResult bindingResult = exception.getBindingResult();
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
            Map<String, String> map = new HashMap<>();
            for (FieldError fieldError : fieldErrors) {
                map.put(fieldError.getField(), fieldError.getDefaultMessage());
            }
            SingleResponse response = new SingleResponse();
            response.setData(map);
            response.setCode("10001");
            response.setMsg("请求参数不合法");
            return response;
        }
    
    
        /**
         * 未知异常
         *
         * @param exception
         * @param webRequest
         * @return
         */
        @ExceptionHandler({Exception.class, NestedServletException.class, IllegalStateException.class})
        public Response handleOtherException(Exception exception, WebRequest webRequest) {
            log.error("global exception handleOtherException", exception);
            return SingleResponse.buildFailure("10000", exception.getMessage());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    4.5 分组校验

    public interface AddValidateGroup {
    }
    
    • 1
    • 2
    public interface UpdateValidateGroup {
    }
    
    • 1
    • 2

    4.6 自定义校验组件

    定义注解

    import javax.validation.Constraint;
    import javax.validation.Payload;
    import java.lang.annotation.Documented;
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    
    import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
    import static java.lang.annotation.ElementType.CONSTRUCTOR;
    import static java.lang.annotation.ElementType.FIELD;
    import static java.lang.annotation.ElementType.METHOD;
    import static java.lang.annotation.ElementType.PARAMETER;
    import static java.lang.annotation.ElementType.TYPE_USE;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    
    @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
    @Retention(RUNTIME)
    @Documented
    @Constraint(validatedBy = {ListValueValidatorForInteger.class})
    public @interface ListValue {
        String message() default "{com.validate.group.ListValue.message}";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    
        int[] value() default {};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    定义校验器

    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    import java.util.HashSet;
    
    public class ListValueValidatorForInteger implements ConstraintValidator<ListValue, Integer> {
    
        private HashSet<Integer> set = new HashSet<>();
    
        @Override
        public void initialize(ListValue listValue) {
            int[] value = listValue.value();
            for (int i : value) {
                set.add(i);
            }
        }
    
        @Override
        public boolean isValid(Integer value, ConstraintValidatorContext context) {
            return set.contains(value);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • 相关阅读:
    浏览器如何进行静态资源缓存?—— 强缓存 & 协商缓存
    vue柱状图+table表格
    前端面试题集锦(3)
    Node.js 教程
    探索 JavaScript ES8 中的函数式编程并通过实例加以实践
    【Centos】深度解析:CentOS下安装pip的完整指南
    MySql添加索引的几种方式
    go学习之数组与Map
    docker安装elasticsearch,elasticsearch-head
    Python入门自学进阶-Web框架——20、Django其他相关知识2
  • 原文地址:https://blog.csdn.net/u010879420/article/details/127654838