数据的校验的重要性,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些HTTP工具直接向后端请求一些违法数据
基础设置搭建
相关依赖
如果是开发普通java程序,依赖如下:
~~~
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.9.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.6</version>
</dependency>
~~~
使用Spring boot程序的话,只需要spring-boot-starter-web就够了,他的子依赖包含了我们所需要的东西。
**实体类**
“`
@Data
public class Person {
@NotNull(message = "classId 不能为空")
private String classId;
@Size(max = 33)
@NotNull(message = "name 不能为空")
private String name;
@Pattern(regexp = "((^Man$|^Woman$|^UGM$))",message = "sex 值不再可选范围")
private String sex;
@Email(message = "email格式不正确")
@NotNull(message = "email 不能为空")
private String email;
}
“`
正则表达式说明:
~~~
– ^string : 匹配以 string 开头的字符串
– string$ :匹配以 string 结尾的字符串
– ^string$ :精确匹配 string 字符串
– ((^Man$|^Woman$|^UGM$)) : 值只能在 Man,Woman,UGM 这三个值中选择
~~~
**JSR提供的校验注解**:
“`
@Null 被注释的元素必须为null
@NotNull 被注释的元素 必须不为null
@AssertTrue 被注释的元素必须为true
@AssertFalse 被注释的元素必须为false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=,min=) 被注释的元素的大小必须在指定的范围内
@Digits(integer,fraction) 被注释的元素必须是一个数字,其值必须在可接收的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
“`
**Hibernate Validator 提供的校验注解**
“`
@NotBlank(message= ) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须式电子邮箱地址
@Length(min=.max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内
“`
**验证Controller的输入**
**验证请求体(RequestBody)**
在需要验证的参数上加上了@valid注解,如果验证失败,它将抛出MethodArgumentNotValidException。默认情况下,Spring会将此异常转换为HTTP Status 400
“`
@RestController
@RequestMapping("/api")
public class PersonController
}
“`
**Exceptionhandler:**
“`
@ControllerAdvice(assignableTypes = {PersonController.class})
public class GlobalExceptionHandler ));
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
}
}
“`
**验证请求参数(Path Variables和 Request Paremeters)**
不要忘记在类上加商@Validated注解,这个参数可以告诉Spring去校验方法参数
“`
@RestController
@RequestMapping("/api")
@Validated
public class PersonController {
@GetMapping("/person/{id}")
public ResponseEntity<Integer> getPersonByID(@Valid @PathVariable("id")
@Max(value=5,message = "超过 id 的范围了") Integer id){
return ResponseEntity.ok().body(id);
}
@PutMapping("/person")
public ResponseEntity<String> getPersonByName(@Valid @RequestParam("name")
@Size(max = 6,message = "超过name的范围了") String nanme){
return ResponseEntity.ok().body(nanme);
}
}
“`
ExceptionHandler:
“`
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<String> handlerConstrainVlidationExcetion(ConstraintViolationException e)
“`
**同样验证Service层的数据**
# Validateor 编程方式手动进行参数验证
*****
某些场景下,可能会需要我们手动校验并获得校验结果
**1、非注解工厂模式模式:**
“`
public void check_person_manually());
}
“`
**2、注解模式:**
“`
@Autowired
Validator validate
“`
# 自定义Validator(常用)
如果自带的校验注解无法满足需求,就可以进行自定义注解
**1、检验特定字段的值是否在可选范围**
比如有如下需求:Person类中多了一个region字段,region字段只能是china,china-taiwan,china-hangkong这三个中的一个
首先新建一个注解
“`
@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = RegionValidator.class)
@Documented
public @interface Region {
String message() default "Region 值不在可选范围内";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
“`
第二步,实现 ConstrainValidator接口,并重写isValid方法
“`
public class RegionValidator implements ConstraintValidator<Region,String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
HashSet<Object> regions = new HashSet<>();
regions.add("China");
regions.add("China-Taiwan");
regions.add("China-HongKong");
return regions.contains(value);
}
}
“`
最后以注解形式使用
“`
@Region
private String region;
“`
**使用验证组**
*****
某些场景下,我们需要使用到验证组,对对象操作的不同方法有不同的验证规则,比如新增的时候,id,不需要验证,在更新和删除时就必须验证
1、先创建两个接口
“`
public interface add{}
public interface delete{}
“`
2、使用方式一:
“`
@NotNull(groups = DeletePersonGroup.class)
@Null(groups = AddPersonGroup.class)
private String group;
“`
3、使用方式二:
“`
@Service
@Validated
public class PersonService {
public void validatePerson(@Valid Person person) {
// do something
}
@Validated(AddPersonGroup.class)
public void validatePersonGroupForAdd(@Valid Person person) {
// do something
}
@Validated(DeletePersonGroup.class)
public void validatePersonGroupForDelete(@Valid Person person) {
// do something
}
}
“`









