• JSR303的使用


    JSR303
    * 1)、给Bean添加校验注解:javax.validation.constraints,并定义自己的message提示
    * 2)、开启校验功能@Valid
    * 效果:校验错误以后会有默认的响应;
    * 3)、给校验的bean后紧跟一个BindingResult,就可以获取到校验的结果
    * 4)、分组校验(多场景的复杂校验)
    * 1)、 @NotBlank(message = "品牌名必须提交",groups = {AddGroup.class,UpdateGroup.class})
    * 给校验注解标注什么情况需要进行校验
    * 2)、@Validated({AddGroup.class})
    * 3)、默认没有指定分组的校验注解@NotBlank,在分组校验情况@Validated({AddGroup.class})下不生效,只会在@Validated生效;
    *
    * 5)、自定义校验
    * 1)、编写一个自定义的校验注解
    * 2)、编写一个自定义的校验器 ConstraintValidator
    * 3)、关联自定义的校验器和自定义的校验注解
    * @Documented
    * @Constraint(validatedBy = { ListValueConstraintValidator.class【可以指定多个不同的校验器,适配不同类型的校验】 })
    * @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
    * @Retention(RUNTIME)
    * public @interface ListValue {
    *
    * 4、统一的异常处理
    * @ControllerAdvice
    * 1)、编写异常处理类,使用@ControllerAdvice。
    * 2)、使用@ExceptionHandler标注方法可以处理的异常。


    1.导入maven依赖

    <dependency>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
                <version>2.0.1.Final</version>
            </dependency>

    2.controller层

    @RestController
    public class BrandController {
    
        /**
         * 保存
         */
        @RequestMapping("/save")
        public R save(@Validated({AddGroup.class}) @RequestBody BrandEntity brand){
            return R.ok();
        }
    
        /**
         * 修改
         */
        @RequestMapping("/update")
        public R update(@Validated({UpdateGroup.class}) @RequestBody BrandEntity brand){
            return R.ok();
        }
        
        /**
         * 修改状态
         */
        @RequestMapping("/update/status")
        public R updateStatus(@Validated(UpdateStatusGroup.class) @RequestBody BrandEntity brand){
            return R.ok();
        }
    }

    3.全局捕获异常

    /**
     * 集中处理所有异常
     */
    @Slf4j
    @RestControllerAdvice
    public class MyExceptionControllerAdvice {
        
        @ExceptionHandler(value= MethodArgumentNotValidException.class)
        public R handleVaildException(MethodArgumentNotValidException e){
            log.error("数据校验出现问题{},异常类型:{}",e.getMessage(),e.getClass());
            BindingResult bindingResult = e.getBindingResult();
    
            Map<String,String> errorMap = new HashMap<>();
            bindingResult.getFieldErrors().forEach((fieldError)->{
                errorMap.put(fieldError.getField(),fieldError.getDefaultMessage());
            });
            return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(),BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",errorMap);
        }
    
        @ExceptionHandler(value = Throwable.class)
        public R handleException(Throwable throwable){
            log.error("错误:",throwable);
            return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg());
        }
    public enum BizCodeEnume {
        UNKNOW_EXCEPTION(10000,"系统未知异常"),
        VAILD_EXCEPTION(10001,"参数格式校验失败");
    
        private int code;
        private String msg;
        BizCodeEnume(int code,String msg){
            this.code = code;
            this.msg = msg;
        }
    
        public int getCode() {
            return code;
        }
    
        public String getMsg() {
            return msg;
        }
    }

    4.自定义返回的结果集

    /**
     * 返回数据
     *
     * @author Mark sunlightcs@gmail.com
     */
    public class R extends HashMap<String, Object> {
        private static final long serialVersionUID = 1L;
        
        public R() {
            put("code", 0);
            put("msg", "success");
        }
        
        public static R error() {
            return error(40001, "未知异常,请联系管理员");
        }
        
        public static R error(String msg) {
            return error(40001, msg);
        }
        
        public static R error(int code, String msg) {
            R r = new R();
            r.put("code", code);
            r.put("msg", msg);
            return r;
        }
    
        public static R ok(String msg) {
            R r = new R();
            r.put("msg", msg);
            return r;
        }
        
        public static R ok(Map<String, Object> map) {
            R r = new R();
            r.putAll(map);
            return r;
        }
        
        public static R ok() {
            return new R();
        }
    
        public R put(String key, Object value) {
            super.put(key, value);
            return this;
        }
        public  Integer getCode() {
    
            return (Integer) this.get("code");
        }
    
    }

    5.javabean对象

    @Data
    public class BrandEntity implements Serializable {
        private static final long serialVersionUID = 1L;
    
        @NotNull(message = "修改必须指定品牌id",groups = {UpdateGroup.class})
        @Null(message = "新增不能指定id",groups = {AddGroup.class})
        private Long brandId;
        /**
         * 品牌名
         */
        @NotBlank(message = "品牌名必须提交")
        private String name;
        /**
         * 品牌logo地址
         */
    
        @URL(message = "logo必须是一个合法的url地址")
        private String logo;
        /**
         * 介绍
         */
        private String descript;
        /**
         * 显示状态[0-不显示;1-显示]
         */
    
        @NotNull(groups = {AddGroup.class, UpdateStatusGroup.class})
         @ListValue(vals={0,1},groups = {AddGroup.class, UpdateStatusGroup.class})
        private Integer showStatus;
        /**
         * 检索首字母
         */
    
        @NotEmpty(message = "首字母不允许为空")
        @Pattern(regexp="^[a-zA-Z]$",message = "检索首字母必须是一个字母")
        private String firstLetter;
        /**
         * 排序
         */
        @NotNull
        @Min(value = 0,message = "排序必须大于等于0")
        @Max(value = 100,message = "排序必须小于等于100")
        private Integer sort;
    
    }

    6.校验的类

    public interface AddGroup {
    }
    public interface UpdateGroup {
    }
    public interface UpdateStatusGroup {
    }

    7.自定义校验器

    @Documented
    @Constraint(validatedBy = { ListValueConstraintValidator.class })
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
    @Retention(RUNTIME)
    public @interface ListValue {
        String message() default "{com.hourui.valid.ListValue.message}";
    
        Class<?>[] groups() default { };
    
        Class<? extends Payload>[] payload() default { };
    
        int[] vals() default { };
    }
    public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
    
        private Set<Integer> set = new HashSet<>();
        //初始化方法
        @Override
        public void initialize(ListValue constraintAnnotation) {
    
            int[] vals = constraintAnnotation.vals();
            for (int val : vals) {
                set.add(val);
            }
    
        }
    
        //判断是否校验成功
        /**
         *
         * @param value 需要校验的值
         * @param context
         * @return
         */
        @Override
        public boolean isValid(Integer value, ConstraintValidatorContext context) {
            return set.contains(value);
        }
    }

    ValidationMessages.properties

    com.hourui.valid.ListValue.message=必须提交指定的值

  • 相关阅读:
    1.8新特性
    线程池
    微服务简介
    缓存三大问题
    Redis分布式锁的正确实现方式
    【java-10&11&12】java语言(Hello World相关)
    【postman】postman 安装失败
    【java-04-09集】JDK的下载和安装&配置环境变量(临时和永久)&命令行方式
    【ISTQB】TM&TA&TTA区别
    【git】学习地址
  • 原文地址:https://www.cnblogs.com/liuyi13535496566/p/13339950.html
Copyright © 2020-2023  润新知