SpringBoot接口参数统一校验( 二 )


文章插图
 
使用spring boot校验器
检验器代码:
@Componentpublic class ValidatorUtil implements ApplicationContextAware {// 通过Spring获得校验器private static Validator validator;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) {Validator validatorBean = applicationContext.getBean(Validator.class);setValidator(validatorBean);public static void setValidator(Validator validatorBean) {if (validatorBean instanceof LocalValidatorFactoryBean) {validator = ((LocalValidatorFactoryBean) validatorBean).getValidator();} else if (validatorBean instanceof SpringValidatorAdapter) {validator = validatorBean.unwrap(Validator.class);} else {validator = validatorBean;public static void validate(T object) {Set> violationSet = validator.validate(object);for (ConstraintViolation violation : violationSet) {throw new ValidationException(violation.getMessage());
统一异常管理:
@RestControllerAdvicepublic class ValidatedExceptionHander {@ExceptionHandler(value = https://www.isolves.com/it/cxkf/jiagou/2022-12-29/ValidationException.class)public String ValidationException(ValidationException exception) {return exception.getMessage();
controller类如下:
@RestController@RequestMapping("validator/")public class ValidatorController {@PostMapping("/add")public String addUser(@RequestBody User user) {ValidatorUtil.validate(user);return "检验通过";
执行如下:

SpringBoot接口参数统一校验

文章插图
 
说明:这么做的好处是可以自由的对实体进行检验,与以上方式相比较为灵活 。
分组校验
同一个实体在不同的操作中的校验方式是不同的,这就要用到分组校验 。比如实体User在新增操作时,id是没有的,但是在更新操作时id又必须存在 。通过下面例子来讲解一下是如何实现的 。
实体user:
public class User {@NotNull(message = "id不能为空", groups = {User.UpdateGroup.class})@Null(message = "id必须为空", groups = {User.InsertGroup.class})public Integer id;@NotBlank(message = "请输入名称")@Length(message = "名称不能超过个 {max} 字符", max = 5)public String name;@NotNull(message = "请输入年龄")@Range(message = "年龄范围为 {min} 到 {max} 之间", min = 1, max = 100)public Integer age;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public interface InsertGroup{}public interface UpdateGroup{}
统一异常:
@RestControllerAdvicepublic class ValidatedExceptionHander {@ExceptionHandler(MethodArgumentNotValidException.class)public String MethodArgumentNotValidHandler(MethodArgumentNotValidException exception) {String exceptionInfo = exception.getBindingResult().getAllErrors().get(0).getDefaultMessage();return exceptionInfo;
controller类:
@RestController@RequestMapping("validator/")public class ValidatorController {@GetMapping("/update")public String updateUser(@Validated(User.UpdateGroup.class) @RequestBody User user) {return "更新成功";@GetMapping("/insert")public String insertUser(@Validated(User.InsertGroup.class) @RequestBody User user) {return "保存成功";
执行如下:
SpringBoot接口参数统一校验

文章插图
 
SpringBoot接口参数统一校验

文章插图
 
@Validated和@Valid区别
@Validated 对@Valid 进行了二次封装,但在分组、注解位置、嵌套验证等功能上有所不同 。
不同点
@Valid
@Validated
是Hibernate validation 的 校验注解
是 Spring Validator 的校验注解,是 Hibernate validation 基础上的增加版
注解位置
【SpringBoot接口参数统一校验】用在 构造函数、方法、方法参数 和 成员属性上
用在 类、方法和方法参数上 。但不能用于成员属性
嵌套验证
用在级联对象的成员属性上面
不支持
分组
无此功能
提供分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制


推荐阅读