在开发中,往往需要对应前端穿过来的参数进行校验,有时候会显得参数校验过于臃肿,但是又不得不做。这里引入 Hibernate Validator ,它支持属性、字段、返回值、方法参数、类级别的校验,而且SpringBoot可以很轻松集成。

Maven

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>

配置

配置 ValidatorFactory

@Configuration
public class ValidatorConfig {@Beanpublic Validator validator() {ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory();return validatorFactory.getValidator();}
}

配置校验失败异常处理。

@ControllerAdvice
public class ExceptionAdvice {@ExceptionHandler(value = MethodArgumentNotValidException.class)public ResponseEntity<ApiResult<?>> methodArgumentNotValidException(MethodArgumentNotValidException exception) {List<ObjectError> allErrors = exception.getBindingResult().getAllErrors();Iterator<ObjectError> iterator = allErrors.iterator();StringBuilder builder = new StringBuilder();while (iterator.hasNext()) {ObjectError error = iterator.next();String message = error.getObjectName() + ":" + error.getDefaultMessage();builder.append(message);}return new ResponseEntity<>(new ApiResult<>(HttpStatus.BAD_REQUEST.value(), builder.toString()), HttpStatus.BAD_REQUEST);}@ExceptionHandler(value = ConstraintViolationException.class)public ResponseEntity<ApiResult<?>> constraintViolationException(ConstraintViolationException exception) {Set<ConstraintViolation<?>> constraintViolations = exception.getConstraintViolations();Iterator<ConstraintViolation<?>> iterator = constraintViolations.iterator();StringBuilder builder = new StringBuilder();while (iterator.hasNext()) {ConstraintViolation<?> constraint = iterator.next();String message = constraint.getPropertyPath() + ":" + constraint.getMessage();builder.append(message);}return new ResponseEntity<>(new ApiResult<>(HttpStatus.BAD_REQUEST.value(), builder.toString()), HttpStatus.BAD_REQUEST);}
}

属性级别校验

@Data
public class Car {@NotNullprivate String manufacturer;@AssertTrueprivate boolean isRegistered;public Car(String manufacturer, boolean isRegistered) {this.manufacturer = manufacturer;this.isRegistered = isRegistered;}
}
controller编写

@Validated 开启参数校验,如果参数校验失败,将抛出 MethodArgumentNotValidException 异常。

@RestController
@RequestMapping("/test")
public class TestController {@PostMapping("/car")public void testCar(@Validated @RequestBody Car car) {System.out.println(car);}
}

get方法开启参数校验,要在类级别上使用 @Validated,如果校验失败,将抛出 ConstraintViolationException 异常。

@RestController
@RequestMapping("/test")
@Validated
public class TestController {@GetMapping("/testGet")public void testGet(@Max(23) Integer id) {System.out.println(id);}
}

分组校验

有时候我们需要对需要校验的字段进行分组,方便复用。这里定义一个对象 GroupDomain,分了三个组。注意:Hibernate Validator 有个默认组的概念,如果校验限制没有被指定分组,那么属于默认分组。idcolumn1 是属于默认分组(Default)。

@Data
public class GroupDomain {@NotNull(message = "id can not null")private Integer id;@NotBlank(message = "column1 can not null")private String column1;@NotBlank(message = "column2 can not null", groups = GroupCheck2.class)private String column2;@NotBlank(message = "column3 can not null", groups = GroupCheck3.class)private String column3;@NotBlank(message = "column4 can not null", groups = GroupCheck4.class)private String column4;
}
public interface GroupCheck2 {}
public interface GroupCheck3 {}
public interface GroupCheck4 {}
controller编写
@RestController
@RequestMapping("/group")
public class GroupController {// id不能为null,column1不能为空串。其他字段不校验@PostMapping("/defaultGroup")public void defaultGroup(@Validated @RequestBody GroupDomain groupDomain) {System.out.println(groupDomain);}// column2不能为空串。其他字段不校验@PostMapping("/oneGroup")public void oneGroup(@Validated(GroupCheck1.class) @RequestBody GroupDomain groupDomain) {System.out.println(groupDomain);}// column3不能为空串。其他字段不校验@PostMapping("/twoGroup")public void twoGroup(@Validated(GroupCheck2.class) @RequestBody GroupDomain groupDomain) {System.out.println(groupDomain);}// column4不能为空串。其他字段不校验@PostMapping("/threeGroup")public void threeGroup(@Validated(GroupCheck3.class) @RequestBody GroupDomain groupDomain) {System.out.println(groupDomain);}
}
分组顺序

当校验指定多个分组时,校验的顺序是不能确定的,我们可以指定分组校验的顺序。

@RestController
@RequestMapping("/group")
public class GroupController {@PostMapping("/fourGroup")public void fourGroup(@Validated(GroupChecks.class) @RequestBody GroupDomain groupDomain) {System.out.println(groupDomain);}
}
@GroupSequence(value = {GroupCheck4.class, GroupCheck3.class, GroupCheck2.class})
public interface GroupChecks {}

级联

使用 @Valid 注解可以使用级联方式校验。

public class Driver {@Min(value = 18, message = "You have to be 18 to drive a car", groups = DriverChecks.class)private int age;@AssertTrue(message = "You first have to pass the driving test", groups = DriverChecks.class)private boolean hasDrivingLicense;// getter and setter
}
public class Car {@NotNullprivate String manufacturer;@NotNull@Size(min = 2, max = 14)private String licensePlate;@Min(2)private int seatCount;@AssertTrue(message = "The car has to pass the vehicle inspection first",groups = CarChecks.class)private boolean passedVehicleInspection;@Validprivate Driver driver;// getter and setter
}

自定义校验

Hibernate validator 内置很多校验注解,它也支持自定义校验注解。

自定义注解,来校验字符串是否为大小写。

定义一个枚举
public enum CaseMode {UPPER, LOWER
}
定义注解

自定义 @CheckCase 注解,有三个属性是必选要有的:messagegroupspayload。注解 @Constraint 来定义由谁去处理被 @CheckCase 标记的JavaBean的属性。

@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE, TYPE_USE })
@Retention(RUNTIME)
@Constraint(validatedBy = CheckCaseValidator.class)
@Documented
@Repeatable(CheckCase.List.class)
public @interface CheckCase {// 这个是必选有的String message() default "{com.example.hibernate.constraint.custom.CheckCase.message}";// 这个是必选有的Class<?>[] groups() default {};// 这个是必选有的Class<? extends Payload>[] payload() default {};CaseMode value();@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })@Retention(RUNTIME)@Documented@interface List {CheckCase[] value();}
}
定义 CheckCaseValidator

自定义 CheckCaseValidator 验证器,它实现了 ConstraintValidator 接口

public class CheckCaseValidator implements ConstraintValidator<CheckCase, String> {private CaseMode caseMode;@Overridepublic boolean isValid(String object, ConstraintValidatorContext constraintValidatorContext) {if (object == null) {return true;}boolean isValid;if (caseMode == CaseMode.UPPER) {isValid = object.equals(object.toUpperCase());} else {isValid = object.equals(object.toLowerCase());}return isValid;}@Overridepublic void initialize(CheckCase constraintAnnotation) {this.caseMode = constraintAnnotation.value();}
}

参考

  • Hibernate Validator官网
  • springboot中hibernate validator校验模式,分组校验,自定义校验_morris131的博客-CSDN博客_validator分组校验

SpringBoot Validator相关推荐

  1. 第十五章:使用SpringBoot validator让数据更真实

    数据验证是作为一个企业级项目架构上设计的最基础的模块,前辈们曾说过:界面上传递到后天的数据没有百分之百值得相信的!为什么这么说呢?往往我们在编写程序的时候都会感觉后台的验证无关紧要,这样就会给别人空子 ...

  2. 目录:SpringBoot学习目录

    SpringBoot配套源码地址:gitee.com/hengboy/spr- SpringCloud配套源码地址:gitee.com/hengboy/spr- SpringBoot相关系列文章请访问 ...

  3. SpringBoot 2 快速整合 | Hibernate Validator 数据校验

    概述 在开发RESTFull API 和普通的表单提交都需要对用户提交的数据进行校验,例如:用户姓名不能为空,年龄必须大于0 等等.这里我们主要说的是后台的校验,在 SpringBoot 中我们可以通 ...

  4. SpringBoot中的Validator参数校验器——通过注解的方式控制controler接收参数的规则

    前言 在日常的接口开发中,经常要对接口的参数做校验,例如,登录的时候要校验用户名密码是否为空.但是这种日常的接口参数校验太烦锁了,代码繁琐又多. Validator框架就是为了解决开发人员在开发的时候 ...

  5. SpringBoot:参数校验的使用(validator)

    文章目录 SpringBoot参数校验的使用(validator) 一.validator简介 二.注解介绍 内置注解 扩展注解 三.validator的使用(手动校验) 创建校验工具类 对一个对象进 ...

  6. springboot使用hibernate validator校验

    回到顶部 一.参数校验 在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,写这些与业务逻辑关系不大的代码个人感觉有两个麻烦: 验证代码繁琐,重复劳动 方法内代码显得冗 ...

  7. SpringBoot中使用Hibernate Validator校验工具类

    1.说明 在Spring Boot已经集成Hibernate Validator校验器的情况下, 对于配置了校验注解的请求参数, 框架会自动校验其参数, 但是如果想手动校验一个加了注解的普通对象, 比 ...

  8. springboot统一校验validator实现

    2019独角兽企业重金招聘Python工程师标准>>> 第一步: pom.xml需引入spring-boot-start-web依赖,其中包含validator框架包 <!-- ...

  9. springboot中hibernate validator校验模式,分组校验,自定义校验

    检验模式 上面例子中一次性返回了所有验证不通过的集合,通常按顺序验证到第一个字段不符合验证要求时,就可以直接拒绝请求了.Hibernate Validator有以下两种验证模式: 普通模式(默认是这个 ...

最新文章

  1. 推荐一位二本毕业1年,上海买房的大佬,牛逼!
  2. 4月书讯:迟来的告白
  3. Android华容道之一步一步实现-8-开始游戏
  4. ipaddr库计算区间IP及CIDR的IP段
  5. POJ1151(矩形切割入门题)
  6. How is HashMap return type handled to be converted to a json string
  7. C语言 内存分配 地址 指针 数组 参数 解析
  8. Android的debug.keystore拒绝访问导致的生成异常及解决方案
  9. Silverlight 2.5D RPG游戏技巧与特效处理:(七)动画特写
  10. 判断应用程序是否是当前激活程序(获得焦点的程序)
  11. python 生成html_Python使用pyh生成HTML文档的方法示例
  12. CentOS安装nginx方法命令教程
  13. 微软发表IE浏览器 F1漏洞安全公告
  14. VS2017下的getch函数
  15. PLC编程入门基础知识
  16. Android调试ABD命令
  17. 模拟银行排队叫号机 2011.04.18
  18. 用winpcap实现局域网DNS欺骗之一(基础知识)
  19. Typora主题下载
  20. Web测试所涉及的主要测试点

热门文章

  1. TTF字体_TTF格式字体_TTF格式字库_TTF格式字体大全_TTF格式字体...
  2. 2023 届校招薪资爆料汇总
  3. 单片机动态从00到99C语言,求用51单片机串口方式0接两个74LS164显示数码管,0-99动态显示(用C语言)...
  4. Quartz2之入门示例
  5. 高考数学复习:任意角、弧度制及任意角的三角函数(解析版一轮复习)
  6. JSON 变量名为数字或数字开头的解决办法
  7. 【已解决】nginx 502 Bad Gateway 问题排查
  8. Zigbee基础知识
  9. 简析CRM实施阻力之独行侠作风
  10. matlab中幅度调制,双边带幅度调制及其MATLAB仿真.pdf