电子说
上一篇文章我们了解了Spring Boot Web相关的知识,初步了解了spring-boot-starter-web,还了解了@Contrler和@RestController的差别,如果使用@Controller注解只返回数据则需要使用@ResponseBody注解。与此同时还了解了@RequestMapping注解与URL映射,URL映射可以分为URL路径匹配、Method匹配、consumes和produces匹配、params和header匹配。这篇文章我们将会介绍数据校验,对于任何应用系统而言,任何客户端传入的数据都不是绝对安全有效的,这就要求我们在服务端接收到数据时需要对传入的数据的有效性进行验证,以确保传入的数据安全正确。
目前数据校验的规范和组件有很多,Spring Boot默认使用的数据校验组件是基于JSR数据校验规范的Hibernate Validator,其中常用的注解如下表所示
注解 | 作用目标 | 检查规则 |
---|---|---|
@NotNull | 属性 | 检查值是否为空 |
@Null | 属性 | 检查值必须为空 |
@AsserFalse | 属性 | 检查演算结果是否为false |
@AssertTrue | 属性 | 检查演算结果是否为true |
@Max(value=) | 属性(以numeric或string类型表示一个数字) | 检查值是否小于或等于最大值 |
@Min(value=) | 属性(以numeric或string类型表示一个数字) | 检查值是否大于或等于最小值 |
@Size(min=, max=) | 属性(array,collection,map) | 检查元素大小是否在最大值和最小值之间(包括临界值) |
@Digits(integer,fraction) | 属性 | 检查元素必须是数字且在范围内 |
@Past | 属性(data或calender) | 检查日期是否是过去的日期 |
@Feature | 属性data或calender) | 检查日期是否是未来的日期 |
@Pattern(regex="rexgex",flag=) | 属性 | 检查值是否与正则表达式匹配 |
@Range(min=,max=) | 属性(以numeric或string类型表示一个数字) | 检查元素大小是否在最大值和最小值之间(包括临界值) |
@Length(min=,max=) | 属性(String) | 检查字符串长度是否符合范围 |
属性(String) | 检查是否是有效的Email地址 | |
@NotEmpty | 属性(String) | 检查字符串不能为空 |
使用Hibernate Validator校验数据需要定义一个接受的数据模型,使用注解的形式描述字段的校验规则,下面以User对象为例说明如何校验数据,先加入以下依赖:
<dependency>
<groupId>org.springframework.boot<span class="hljs-name"groupId>
<artifactId>spring-boot-starter-validation<span class="hljs-name"artifactId>
<span class="hljs-name"dependency>
Post请求参数较多时可以在对应的数据模型(Java Bean)中进行校验,通过注解来指定字段校验的规则。
public class User {
@NotBlank(message = "姓名不允许为空")
@Length(min = 2, max = 10, message = "姓名长度错误,姓名长度2-10")
private String Name;
@NotNull(message = "年龄不能为空!")
@Min(18)
private int age;
@NotBlank(message = "地址不能为空!")
private String address;
@Email(message = "邮箱格式错误")
private String email;
//省略get和set方法
}
上述例子中,每个message是数据校验不通过时要给出的提示信息。然后需要添加数据校验方法。
@PostMapping(path = "/check")
public String check(@RequestBody @Valid User user, BindingResult result) {
String name = user.getName();
if (result.hasErrors()) {
List
上面例子中BindingResult是验证不通过的结果集合,必须跟在被校验参数后,若被校验参数之后没有BindingResult则会抛出BindException异常。
在对象的普通属性上我们可以直接使用注解进行数据校验,对于关联对象也很容易,在关联对象上添加@Valid注解,关联对象内部可以正常使用数据校验注解。代码如下:
public class User {
@NotBlank(message = "姓名不允许为空")
@Length(min = 2, max = 10, message = "姓名长度错误,姓名长度2-10")
private String Name;
@NotNull(message = "年龄不能为空!")
@Min(18)
private int age;
@NotBlank(message = "地址不能为空!")
private String address;
@Email(message = "邮箱格式错误")
private String email;
@NotNull(message = "detail不能为空")
@Valid
private UserDetail detail;
//省略get和set方法
}
public class UserDetail {
@NotNull(message = "id不能为空")
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
在不同的情况下,可能对相同javaBean对象的数据校验规则有所不同,有时需要根据状态数据对javaBean中的某些属性字段进行单独验证。这时候就可以使用分组校验功能,即根据状态启用一组约束,Hibernate Validator的注解提供了groups参数用于指定分组,如果没有指定groups参数,则默认属于javax.validation.groups.Default。接下来我们举例来说明这一过程。
首先创建分组GroupA和GroupB如下,这两个接口作为两个校验规则的分组。
public interface GroupA {
}
public interface GroupB {
}
然后创建实体类Person,并在相关字段定义分组校验规则。
public class Person {
@NotBlank(message = "userId不能为空", groups = {GroupA.class})
private String userId;
@NotBlank(message = "用户名不能为空", groups = {GroupB.class})
private String name;
@Range(min=20, max = 30, message = "年龄必须在【20,30】", groups = {GroupA.class})
@Range(min = 30, max = 40, message = "年龄必须在【30,40】", groups = {GroupB.class})
private int age;
//省略来get方法和set方法
}
上述例子中,在age
字段使用了两个校验规则,GroupA年龄要在20-30,GroupB年龄要在30-40。最后使用分组:
@RequestMapping("/save")
public String save(@RequestBody @Validated({ GroupA.class, Default.class}) Person person, BindingResult result) {
if (result.hasErrors()) {
List
其中@Validated
注解中增加了{GroupA.class, Default.class}参数表示对于定义了分组校验规则的字段使用GroupA规则,其他使用默认规则。
全部0条评论
快来发表一下你的评论吧 !