Validation
在开发中,会经常需要进行参数的校验,比如接口层、业务层、持久层等,其
中接口的参数校验就是最为常见的。这里就来看一下 springboot 中参数校验(validation)的使用。
validation引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
可用约束(constraint)
hibernate-validator 沿用了 validation-api 中的所有注解约束,同时也定义
了一些自己的约束:
constraint | 描述 | 来源 |
---|---|---|
@AssertFalse | 被约束的元素必须是false | validation-api |
@AssertTrue | 被约束的元素必须是true | validation-api |
@DecimalMax | 被约束的元素必须是数字且其必须小于等于指定值 | validation-api |
@DecimalMin | 被约束的元素必须是数字且其必须大于等于指定值 | validation-api |
@Digits | 被约束的元素必须是数字且其在约束范围内 | validation-api |
@Future | 被约束的元素是未来的时间 | validation-api |
@Past | 被约束的元素是过去的时间 | validation-api |
@Max | 被约束的元素是数字且其必须小于等于指定值 | validation-api |
@Min | 被约束的元素是数字且其必须大于等于指定值 | validation-api |
@NotNull | 被约束的元素不能为Null | validation-api |
@Null | 被约束的元素必须为Null | validation-api |
@Pattern | 被约束的元素必须符合指定的正则表达式 | validation-api |
@Size | 被约束的元素必须在范围内 | validation-api |
@URL | 被约束的元素必须是一个URL | hiberate-validator |
@ScriptAssert | 验证类级别脚本 | hiberate-validator |
@SafeHtml | 被约束的元素必须是要给HTML | hiberate-validator |
@Range | 被约束的元素必须是在[min,max]范围 | hiberate-validator |
@ParameterScriptAssert | 验证参数级别脚本 | hiberate-validator |
@NotEmpty | 验证字符串、集合、字典或数组是否为null或者空 | hiberate-validator |
@NotBlank | 验证字符串是否为null或者空(支持去两端空字符) | hiberate-validator |
@Length | 验证字符串长度范围[min,max] | hiberate-validator |
验证是否为email | hiberate-validator | |
@EAN | 检测字符序列是否有效 | hiberate-validator |
@CreditCardNumber | 验证身份认证是否有效 | hiberate-validator |
使用举例
- 单参数校验,类上必须加
@Validated
@Validated
@RestController
@RequestMapping("/student")
public class StudentApi {
@GetMapping("/queryById")
public Student queryById(@RequestParam("code")
@NotBlank(message = "code not null")
@Length(min = 4, max = 4,message = "长度必须为4")
String id) {
Student student = new Student();
if ("1001".equals(id)) {
student.setCode("1001");
student.setName("Forward");
student.setAge(21);
student.setBirthday(new Date());
}
return student;
}
}
测试响应成功!
当不满足约束时:
- 使用一个对象来接收参数,只需要在对象中约束属性即可。
@Data
public class StudentInsertForm {
@NotBlank
@Length(min = 1, max = 15)
@Pattern(regexp = "[A-z]")
private String name;
@NotNull
@Range(min = 1, max = 100, message = "年龄范围须在1-100之间")
private Integer age;
private Date birth;
}
/**
* 使用封装的对象接收实体参数(Form对象)
* 最常用
* @RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的)
*/
@PostMapping("/insert")
public String insert(@RequestBody @Validated StudentInsertForm form) {
System.out.println(form.getName());
System.out.println(form.getAge());
System.out.println(form.getBirth());
return "success";
}
当参数不满足约束时:
- 当使用对象接收参数时,很多时候可能因为参数个数的不同而造成类的冗余,这时我们可以使用约束的groups字段
比如说,我们插入只用到3个字段,而修改时还需要一个主键code字段,正常情况下我们创建两个类,而使用group字段,只需要创建接口。
创建对应功能的接口,接口中不需要写任何东西:
public interface Insert {
}
public interface Update {
}
接收参数的实体类:
哪个功能需要该字段,就在groups参数中添加上该功能的接口
@Data
public class StudentForm {
@NotNull(groups = {Update.class})
@Length(min = 4, max = 6, groups = {Update.class})
private String code;
@NotBlank
@Length(min = 1, max = 15, groups = {Update.class, Insert.class})
@Pattern(regexp = "[A-z]", groups = {Update.class, Insert.class})
private String name;
@NotNull(groups = {Update.class, Insert.class})
@Range(min = 1, max = 100, message = "年龄范围须在1-100之间", groups = {Update.class, Insert.class})
private Integer age;
private Date birth;
}
最后在用到对应功能的地方加上功能接口
@PostMapping("/insert2")
public String insert2(@RequestBody @Validated({Insert.class}) StudentForm form) {
System.out.println(form.getName());
System.out.println(form.getAge());
System.out.println(form.getBirth());
return "success";
}
@PostMapping("/update")
public String update(@RequestBody @Validated({Update.class}) StudentForm form) {
System.out.println(form.getCode());
System.out.println(form.getName());
System.out.println(form.getAge());
System.out.println(form.getBirth());
return "success";
}