SpringBoot Validator
在开发中,往往需要对应前端穿过来的参数进行校验,有时候会显得参数校验过于臃肿,但是又不得不做。这里引入 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
有个默认组的概念,如果校验限制没有被指定分组,那么属于默认分组。id
、column1
是属于默认分组(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
注解,有三个属性是必选要有的:message
、groups
、payload
。注解 @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相关推荐
- 第十五章:使用SpringBoot validator让数据更真实
数据验证是作为一个企业级项目架构上设计的最基础的模块,前辈们曾说过:界面上传递到后天的数据没有百分之百值得相信的!为什么这么说呢?往往我们在编写程序的时候都会感觉后台的验证无关紧要,这样就会给别人空子 ...
- 目录:SpringBoot学习目录
SpringBoot配套源码地址:gitee.com/hengboy/spr- SpringCloud配套源码地址:gitee.com/hengboy/spr- SpringBoot相关系列文章请访问 ...
- SpringBoot 2 快速整合 | Hibernate Validator 数据校验
概述 在开发RESTFull API 和普通的表单提交都需要对用户提交的数据进行校验,例如:用户姓名不能为空,年龄必须大于0 等等.这里我们主要说的是后台的校验,在 SpringBoot 中我们可以通 ...
- SpringBoot中的Validator参数校验器——通过注解的方式控制controler接收参数的规则
前言 在日常的接口开发中,经常要对接口的参数做校验,例如,登录的时候要校验用户名密码是否为空.但是这种日常的接口参数校验太烦锁了,代码繁琐又多. Validator框架就是为了解决开发人员在开发的时候 ...
- SpringBoot:参数校验的使用(validator)
文章目录 SpringBoot参数校验的使用(validator) 一.validator简介 二.注解介绍 内置注解 扩展注解 三.validator的使用(手动校验) 创建校验工具类 对一个对象进 ...
- springboot使用hibernate validator校验
回到顶部 一.参数校验 在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,写这些与业务逻辑关系不大的代码个人感觉有两个麻烦: 验证代码繁琐,重复劳动 方法内代码显得冗 ...
- SpringBoot中使用Hibernate Validator校验工具类
1.说明 在Spring Boot已经集成Hibernate Validator校验器的情况下, 对于配置了校验注解的请求参数, 框架会自动校验其参数, 但是如果想手动校验一个加了注解的普通对象, 比 ...
- springboot统一校验validator实现
2019独角兽企业重金招聘Python工程师标准>>> 第一步: pom.xml需引入spring-boot-start-web依赖,其中包含validator框架包 <!-- ...
- springboot中hibernate validator校验模式,分组校验,自定义校验
检验模式 上面例子中一次性返回了所有验证不通过的集合,通常按顺序验证到第一个字段不符合验证要求时,就可以直接拒绝请求了.Hibernate Validator有以下两种验证模式: 普通模式(默认是这个 ...
最新文章
- 推荐一位二本毕业1年,上海买房的大佬,牛逼!
- 4月书讯:迟来的告白
- Android华容道之一步一步实现-8-开始游戏
- ipaddr库计算区间IP及CIDR的IP段
- POJ1151(矩形切割入门题)
- How is HashMap return type handled to be converted to a json string
- C语言 内存分配 地址 指针 数组 参数 解析
- Android的debug.keystore拒绝访问导致的生成异常及解决方案
- Silverlight 2.5D RPG游戏技巧与特效处理:(七)动画特写
- 判断应用程序是否是当前激活程序(获得焦点的程序)
- python 生成html_Python使用pyh生成HTML文档的方法示例
- CentOS安装nginx方法命令教程
- 微软发表IE浏览器 F1漏洞安全公告
- VS2017下的getch函数
- PLC编程入门基础知识
- Android调试ABD命令
- 模拟银行排队叫号机 2011.04.18
- 用winpcap实现局域网DNS欺骗之一(基础知识)
- Typora主题下载
- Web测试所涉及的主要测试点
热门文章
- TTF字体_TTF格式字体_TTF格式字库_TTF格式字体大全_TTF格式字体...
- 2023 届校招薪资爆料汇总
- 单片机动态从00到99C语言,求用51单片机串口方式0接两个74LS164显示数码管,0-99动态显示(用C语言)...
- Quartz2之入门示例
- 高考数学复习:任意角、弧度制及任意角的三角函数(解析版一轮复习)
- JSON 变量名为数字或数字开头的解决办法
- 【已解决】nginx 502 Bad Gateway 问题排查
- Zigbee基础知识
- 简析CRM实施阻力之独行侠作风
- matlab中幅度调制,双边带幅度调制及其MATLAB仿真.pdf