springboot@valid与@validated的参数校验使⽤总结

 @Valid只能⽤在controller,@Validated可以⽤在其他被spring管理的类上
 @Valid可以加在成员变量上(本⼈⼀般只有在嵌套查询的时候才会使⽤这个注解)
 @Validated可以分组
 @Valid可以加在成员变量上,所以可以嵌套校验

@RestController
@RequestMapping("/check")
@Validated
publicclass ParamCheckInController {
    @Autowired
private ParamCheckInService paramCheckInService;
    @PostMapping("/postDemo")
public Node postDemo(@RequestBody @Validated Node node) {
return node;
    }
    @GetMapping("/getDemo")
public Node getDemo(@Validated Node node) {
        paramCheckInService.test("a","b");
return node;
    }
    @GetMapping("/getDemo2")
public String getDemo2( @NotEmpty  String s) {
return s;
    }
    @PostMapping("/groupDemo1")
public Book groupDemo1(@RequestBody @Validated Book book) {
return book;
    }
    @PostMapping("/groupDemo2")
public Book groupDemo2(@RequestBody @Validated({InsertGroup.class}) Book book) {
return book;
    }
    @PostMapping("/groupDemo3")
public Node groupDemo3(@RequestBody @Validated({InsertGroup.class,UpdateGroup.class}) Node node) {//还有啥@Validated分组是有序校验的之类,感觉没啥⽤
return node;
    }
}
@Data
class Node implements Serializable {
    @NotBlank(message = "名称不能为空")
private String name;
    @NotEmpty(groups = UpdateGroup.class,message = "性别不能为空")
private String sex;
    @NotNull(groups =InsertGroup.class,message = "年龄不能为空")
    @Max(value = 200,message = "age不能⼤于200")
private Integer age;
    @Valid      //对下层进⾏嵌套调⽤
    @NotEmpty(message = "bookList不能为空")
private List<Book> bookList;
}
@Data
class Book implements Serializable{
    @NotEmpty(groups = {UpdateGroup.class, Default.class}, message = "更新时id不能为空")
private String id;
    @NotNull(groups = {InsertGroup.class}, message = "新增时bookName不能为空")
private String bookName;
}
@Service
@Slf4j
@Validated
publicclass ParamCheckInService {
public @NotNull(message = "返回值不允许为空") String test(@NotEmpty(message = "s不能为空") String s,String b){
return b;
    }

全局异常捕获

  • BindException:表单提交有效,对于以json格式提交将会失效
  • MethodArgumentNotValidException:前端以json格式有效
  • ConstraintViolationException:参数上加@RequestParam或参数加@NotBlank @NotNull等
@RestControllerAdvice
public class GlodException {
     private static final Logger log = LoggerFactory.getLogger(GlodException.class);
    /**
     * 处理 SpringMVC 参数绑定不正确
     * 在全局异常处理里编写
     * Validator,valid 校验参数 参数不正确报错处理
     * BindException异常针对表单提交有效,对于以json格式提交将会失效
     */
    @ExceptionHandler(BindException.class)
    public Result<?> bindExceptionHandler(BindException ex) {
        log.error(ex.getMessage(),ex);
        //单个和全部 任选其一即可
        //获取单个错误数据
       /* Map<String,Object> restultMap = new HashMap<String,Object>();
        FieldError fieldError = ex.getFieldError();
        String field = fieldError.getField();
        String defaultMessage = fieldError.getDefaultMessage();
        String message = restultMap.toString();
        return Result.error(500,message);*/

        //获取全部错误数据
        List<FieldError> fieldErrors = ex.getFieldErrors();
        Map<String,Object> restultMap = new HashMap<String,Object>();
        for (FieldError fieldError:fieldErrors) {
            //获取错误字段
            String field = fieldError.getField();
            //获取错误信息
            String defaultMessage = fieldError.getDefaultMessage();
            restultMap.put(field,defaultMessage);
        }
        String message = restultMap.toString();
        return Result.error(500,message);
    }

    /**
     * 处理 SpringMVC 参数绑定不正确
     * 在全局异常处理里编写
     * Validator,valid 校验参数 参数不正确报错处理
     * MethodArgumentNotValidException异常针对前端以json格式有效
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<?> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException ex) {

        log.error(ex.getMessage(),ex);
        //单个和全部 任选其一即可
        //获取单个错误数据
       /* Map<String,Object> restultMap = new HashMap<String,Object>();
        BindingResult bindingResult = ex.getBindingResult();
        FieldError fieldError = bindingResult.getFieldError();
        String field = fieldError.getField();
        String defaultMessage = fieldError.getDefaultMessage();
        String message = restultMap.toString();
        return Result.error(500,message);*/
        //获取全部错误数据
        BindingResult bindingResult = ex.getBindingResult();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        Map<String,Object> restultMap = new HashMap<String,Object>();
        for (FieldError fieldError:fieldErrors) {
            //获取错误字段
            String field = fieldError.getField();
            //获取错误信息
            String defaultMessage = fieldError.getDefaultMessage();
            restultMap.put(field,defaultMessage);
        }
        String message = restultMap.toString();
        return Result.error(500,message);
    }

    /**
     * 处理 SpringMVC 参数绑定不正确
     * 在全局异常处理里编写
     * Validator,valid 校验参数 参数不正确报错处理
     * ConstraintViolationException异常针对参数上加@RequestParam或参数加@NotBlank @NotNull            
     * 等
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result<?> constraintViolationExceptionHandler(ConstraintViolationException ex) {

        log.error(ex.getMessage(),ex);
        //获取全部错误数据
        Map<String,Object> restultMap = new HashMap<String,Object>();
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        for(ConstraintViolation<?> constraintViolation : constraintViolations){
            //返回值为 路径.参数 例如 query.name  可以通过截取只取参数
            //String key = constraintViolation.getPropertyPath().toString().split("\\.")        [1];  只要参数
            String key = constraintViolation.getPropertyPath().toString();
            String message = constraintViolation.getMessage();
            restultMap.put(key,message);
        }
        String message = restultMap.toString();
        return Result.error(500,message);
    }
}

分组校验

  1. 创建分组,分组是一个接口(接口中无方法),同时可以继承其他的组,这里创建一个Selcet和一个Insert,表示查询和新增分组。
    public interface Select {
    }
    public interface Insert {
    }
    
  2. 创建Person类,添加校验注解及指定分组
    @Data
    public class Person {
    
        /**
         * controller层必须写为@Validated({分组1.class,分组2.class})才能对添加了分组的属性进行校验
         * 如果controller层写为@Validated只能对没有添加分组的属性进行校验,并不能对有分组属性和没有分                
         * 组属性的一起校验
         * 即使分组接口继承了Default接口也不行
         */
    
        @NotNull(message = "personId不能为null",groups = Select.class)
        private Integer personId;
    
        @NotEmpty(message = "name不能为空",groups = Insert.class)
        private String name;
    
        @NotNull(message = "请输入年龄")
        @Range(message = "年龄范围为 {min} 到 {max} 之间", min = 1, max = 100)
        private Integer age;
    }
    
  3. 创建查询和新增接口,添加@Validated注解,指定分组,可多个。
    @GetMapping("/select")
    public Object select(@Validated({Select.class}) Person person) {
        return person;
    }

    @GetMapping("/insert")
    public Object insert(@Validated(Insert.class) Person person) {
        return person;
    }

 校验注解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值