
本文共 6709 字,大约阅读时间需要 22 分钟。
文章目录
Spring boot 参数校验
上一节 Spring boot crud 和 swagger使用
源码
springboot web模板已经自动集成了 hibernate-validator; 所以我们引入 spring-boot-starter-web 即可使用;
简介
java 参数校验;是遵循JSR-303 规范,对这种规范实现支持最好的就是 Hibernate Validator; spring 底层也是使用的hibernate validator。简化了 我们在硬编码对参数和bean的校验。
基本数据类型参数校验(包括string,以及基本数据类型的包装类)
请求只接受一个基本类型参数的时候(包括string)不是一个bean;
我们需要在类上加@Validated 然后在方法参数上加上对应的校验注解我们以String 类型参数为例
使用@Length对string 长度的校验
// 类上加注解 @Validated@Validatedpublic class ProductController { // 参数中使用校JSR303 bean校验注解@GetMapping("product")public Product getProduct(@Length(max = 32, min = 32) @RequestParam String id) throws Exception { ...}}
通过swagger 调用; 上面我们限制了 id的长度为32, 我们输入一个错误的长度

实体参数校验
对参数bean进行校验。我们在实体类上使用注解
例如 : - @NotBlank 不能为null以及空白字符 - @Max 最大值 - @Min 最小值public class Product { @ApiModelProperty(required = true, value = "商品名称") @NotBlank @Length(min = 1, max = 500) private String name; @ApiModelProperty(required = true, value = "商品id") @NotBlank @Length(max = 32, min = 32) private String id; @ApiModelProperty(required = true, value = "商品价格,以分为单位", dataType = "java.lang.Long", example = "1000") @Max(Integer.MAX_VALUE) @Min(0) private Long price;
上面对实体类Product 进行了name的长度和不能为空白的校验以及id长度限制,price最大值最小值
请求方法添加@Validated 开启校验
@ApiOperation(value = "添加商品信息", httpMethod = "POST") @PostMapping("product") public String addProduct(@Validated Product product) throws Exception { return product.getId(); }
使用swagger 调用; 返回400,并且是一组json格式的校验信息很不友好;下个章节对全局异常的处理,设置返回我们自己封装的信息。更加友好简短的返回体
{ "timestamp": "2021-03-31T08:47:28.158+0000", "status": 400, "error": "Bad Request", "errors": [ { "codes": [ "Length.product.id", "Length.id", "Length.java.lang.String", "Length" ], "arguments": [ { "codes": [ "product.id", "id" ], "arguments": null, "defaultMessage": "id", "code": "id" }, 32, 32 ], "defaultMessage": "长度需要在32和32之间", "objectName": "product", "field": "id", "rejectedValue": "111", "bindingFailure": false, "code": "Length" } ], "message": "Validation failed for object='product'. Error count: 1", "path": "/validator/product"}
分组校验
@Validated 是spring 提供的注解,支持分组校验;通过groups 属性进行分组
例如: @Length(min = 32, max = 32, message = "orderId 长度为32", groups = OrderGroup.class) 通过 属性groups 进行指定是那个组,不指定默认spring提供了javax.validation.groups.Default 分组
- 创建自定义分组
public interface OrderGroup { }
- 需要校验得实体bean上进行分组指定 orderGroup
@ApiModel(description = "订单信息描述")public class OrderEntity { @ApiModelProperty(required = true, value = "订单编号") @Length(min = 32, max = 32, message = "orderId 长度为32", groups = OrderGroup.class) @NotBlank(message = "orderId 必填") private String orderId;...
- 请求指定分组校验
@ApiOperation(value = "添加订单", httpMethod = "POST", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) @PostMapping("order") public String addOrder(@Validated({ Default.class, OrderEntity.OrderGroup.class}) @RequestBody OrderEntity orderEntity) throws Exception { return orderEntity.getOrderId(); }
通过@validated value 可以指定多个分组同时生效,Default.class 为默认分组,若不指定则默认Default.class分组。
示例代码中 属性orderId 同时使用了@Length 和 @NotBlank校验注解; 并且同时指定了分组default 和orderGroup,
所以@Length 和 @NotBlank 都会生效;若不指定分组则默认 @NotBlank 生效;也可以指定多个同时生效。嵌套校验
使用@Valid 进行实体的嵌套校验。
@Valid 是java自带的校验注解;支持属性嵌套参数校验; 主要是 对实体bean的级联校验;在实体的属性上添加@Valid
@ApiModel(description = "订单信息描述")public class OrderEntity { ... @ApiModelProperty(required = true, value = "订单详情") @NotNull @Valid private OrderInfo orderInfo; ...
OrderInfo 是 OrderEntity 的一个属性; OrderInfo 的属性也添加校验注解,则 对属性 OrderEntity.orderInfo.orderSorce 的校验也生效
@ApiModel(description = "订单扩展详情") public class OrderInfo { @ApiModelProperty(value = "订单来源", required = true) @Length(max = 32, min = 1) @NotBlank private String orderSource;
常用校验注解
注解 | 说明 | 备注 |
---|---|---|
@AssertFalse | 断言为false | JSR303 |
@AssertTrue | 断言为true | JSR303 |
@DecimalMax | 必须为一个数字,值必须小于或者等于指定的值 | JSR303 |
@DecimalMin | 必须为一个数字,值必须大于或者等于指定的值 | JSR303 |
@Digits | 元素必须是可接受范围内的数字 | JSR303 |
email格式 | JSR303 | |
@Future | 标注在时间类型上,必须是一个未来的时间 | JSR303 |
@FutureOrPresent | 标注在时间类型上,必须是一个未来的时间或者当前 | JSR303 |
@Max | 最大值 | JSR303 |
@Min | 最小值 | JAR303 |
@Negative | 元素必须是严格的负数 | JSR303 |
@NegativeOrZero | 负数或者0 | JSR303 |
@NotBlank | 不能为null和空白 | JSR303 |
@NotEmpty | 不能为null和空字符 | JSR303 |
@NotNull | not null | JSR303 |
@Null | 必须为null | JSR303 |
@Past | 标注在时间类型上,必须为一个过去的时间 | JSR303 |
@PastOrPresent | 标注在时间类型上,为一个过去或者现在的时间 | JSR303 |
@Pattern | 是否匹配正则 | JSR303 |
@Positive | 正数,不包括0 | JSR303 |
@PositiveOrZero | 正数,或者0 | JSR303 |
@Size | 集合大小或者字符串长度限制 | JSR303 |
@Length | 校验字符串长度 | Hibernate 提供 |
@Range | 值得范围 | Hibernate 提供 |
@URL | 合法url | Hibernate 提供 |
自定义校验
通过 @Constraint 指定具体的校验器
示例:- 自定义注解 @FileSufixx 校验文件后缀
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})@Documented@Repeatable(value = FileSufixx.List.class)@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy = ValidatedFileSufixx.class)public @interface FileSufixx { String value() default "docx"; String message() default "上传的文件类型不对,请检查"; Class [] groups() default { }; Class [] payload() default { }; @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE}) @Documented @Retention(RetentionPolicy.RUNTIME) @interface List { FileSufixx[] value(); }}
通过@Constraint(validatedBy = ValidatedFileSufixx.class) 指定校验器
2. 编写校验器 在方法isValid 进行文件后缀名称的判断public class ValidatedFileSufixx implements ConstraintValidator{ private String fileSufixx; @Override public boolean isValid(MultipartFile value, ConstraintValidatorContext context) { if (fileSufixx == null || fileSufixx.trim().equals("")) return true; String originalFilename = value.getOriginalFilename(); if (originalFilename.contains(".")) { if (originalFilename.substring(originalFilename.lastIndexOf(".") + 1).equals(fileSufixx)) { return true; } } return false; } @Override public void initialize(FileSufixx constraintAnnotation) { fileSufixx = constraintAnnotation.value(); }}
- 请求中使用 上传文件,会走我们自定义的校验器进行文件后缀的校验
@ApiOperation(value = "上传", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public void upload(@RequestPart("file") @FileSufixx MultipartFile file) { System.out.println(file.getOriginalFilename()); }
下一节 Spring boot 异常配置
发表评论
最新留言
关于作者
