谈谈对SpringBoot的校验机制

谈起校验就不得不说@Valid和@Valitdated的区别
①:分组验证

②:注解位置
 
③:嵌套验证

这里着重谈一下嵌套验证。
什么是嵌套验证?
这个是一个登录信息,它里面可能包含用户信息

//登录信息
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class LoginUser {

    //用户名
    @NotNull(message = "用户名不能为空")
    @Min(value = 2, message = "用户名必须大于两位")
    private String username;

    //密码
    @NotNull(message = "密码不能为空")
    @Min(value = 6, message = "密码必须大于六位")
    private String password;

    //用户信息
    @NotNull(message = "用户信息不能为空")
    private Set<User> roles;

}
//用户信息
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class User {

    //身份证号
    @NotNull(message = "身份证号不能为空")
    private String roleId;

    //地址
    @NotNull(message = "地址不能为空")
    private String ipAddr;
}

 ↓此刻如果在controller方法形参前无论是加@Validated或者Valid,Spring只会对用户名,密码,和用户信息校验,但是,,不会对用户信息里面的身份证号以及地址进行非空校验。

@RestController
@RequestMapping(value = "/person")
public class CheckUser {

    @PostMapping(value="/checkK")
    public String checkU(@Validated @RequestBody LoginUser loginUser, BindingResult bindingResult) {

        //TODO
        return null;
    }

}

如果想嵌套校验,怎么解决呢↓
在用户信息属性上写@Valid的注解(注意:这里不能写@Validated,原因在上面写着:@Validated不可以加在成员属性上)

    //用户信息
    @Valid // 嵌套验证必须用@Valid
    @NotNull(message = "用户信息不能为空")
    private Set<User> roles;

了解以上区别之后,再讲一下springboot的校验机制。
校验机制主要有两种
①:SpringMVC校验(↑的校验方式就是这种)
②:AOP校验
区别:

先后顺序:
SpringMVC校验→AOP校验


!!注意:如果形参前面是@RequestBody+@Validated的话,校验失败时抛得异常是MethodArgumentNotValidException而不是BindException。当形参只有@Validated的话抛的是BindException
 

验证一下结论:首先写一个全局异常处理

@RestControllerAdvice
public class ExceptionAdivce {

    //AOP校验
    @ResponseBody
    @ExceptionHandler(value= ConstraintViolationException.class)
    public Map erroHandleAop(ConstraintViolationException ex){
    Map map = new HashMap();
        map.put("message",ex.getMessage());
    return map;
}

    //spring校验(@RequestBody+@Validated)
    @ResponseBody
    @ExceptionHandler(value= MethodArgumentNotValidException.class)
    public Map erroHandleSpring(MethodArgumentNotValidException ex){
    Map map = new HashMap();
    map.put("message",ex.getMessage());
    return map;
}


    //spring校验(@Validated)
    @ResponseBody
    @ExceptionHandler(value= BindException.class)
    public Map erroHandleSpring1(BindException ex){
        Map map = new HashMap();
        map.put("message",ex.getMessage());
        return map;
    }
}

①:AOP

//AOP
@Validated
@RestController
@RequestMapping(value = "/person")
public class CheckUser {

    @PostMapping(value="/checkK")
    public String checkU( @Valid LoginUser loginUser,BindingResult result) {

        //TODO
        return null;
    }

}

②:Valid

//Valid
@RestController
@RequestMapping(value = "/person")
public class CheckUser {

    @PostMapping(value="/checkK")
    public String checkU( @Valid LoginUser loginUser) {

        //TODO
        return null;
    }

}

③:Valid+RequestBody

//Valid+RequestBody
@RestController
@RequestMapping(value = "/person")
public class CheckUser {

    @PostMapping(value="/checkK")
    public String checkU( @Valid @RequestBody LoginUser loginUser) {

        //TODO
        return null;
    }

}

先后顺序验证:在postman里故意把这里面既有springmvc校验和AOP校验都不符合,看看先走哪一个?

//这里面既有springmvc校验和AOP校验
@Validated
@RestController
@RequestMapping(value = "/person")
public class CheckUser {

    @PostMapping(value="/checkK")
    public String checkU(@Valid @RequestBody LoginUser loginUser, @NotNull String ip)  {

        //TODO
        return null;
    }

}

答案出来了,先走的spring校验

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值