参数校验的使用
- 前言
- 一、何为参数校验?
- 二、如何进行参数校验
- 2.1普通参数类型校验
- 2.2对象类型参数校验
- 2.3对象中还有对象的校验
- 2.3自定义注解对参数进行校验
- 2.3.1 创建一个注解
- 2.3.2 实现ConstraintValidator接口
- 总结
前言
在服务端中需要接收前端发送过来的请求并且进行处理,而这些请求往往是附带参数的,对参数的处理是非常重要的一环,下面简单介绍一下使用注解来对参数进行校验
一、何为参数校验?
参数校验,顾名思义就是对请求(url)所附带的参数进行验证。
https://www.baidu.com/s?ie=UTF-8&wd=JSR303
上面这段请求中?后面的内容就是参数(参数是以键值对的形式出现),还有的参数并不会出现在url上,他们会包含在请求体中,通过url是看不到了。
二、如何进行参数校验
2.1普通参数类型校验
在控制器的方法的参数前打上对应的注解,即可对参数进行相应功能的校验。
如要对一个传入的id进行约束,要求不能超过100,相应代码为:
@RestController
@RequestMapping("/banner")
@Validated
public class BannerController {
@PostMapping("/test/{id}")
public String test(@PathVariable @Max(100) int id){
return null;
}
}
在int id前面打上@Max(100)这个注解,可以实现对id的校验功能,如果请求传入的id值超过了100,那么就会报出相应的错误。
注意:需要在类的前面加上@Validated注解才能够开启校验,只打上@Max注解是不会生效的。
2.2对象类型参数校验
当参数是一个自定义的类时,这是应该怎么样对参数进行校验呢?
需要将注解打在类的成员变量上,然后再控制器方法的参数前打上@Validated注解开启,对类的内部成员进行校验
自定义的类为:
public class PersonDTO {
@Length(max = 5)
private String name;
@Range(min = 18,max = 30)
private Integer age;
//getter 和 setter
.....
}
在类的成员变量上打上要验证的注解
控制器的方法为:
@PostMapping("/test/{id}")
public String test(@PathVariable @Max(10) int id,
@RequestBody @Validated PersonDTO personDTO){
return null;
}
需要在personDTO这个参数前打上@Validated注解,开启对自定义类型的成员进行校验
2.3对象中还有对象的校验
在上面对象校验的基础上,PersonDTO增加一个成员变量,也是自定义的类型。
public class PersonDTO {
@Length(max = 5)
private String name;
@Range(min = 18,max = 30)
private Integer age;
@Valid
private SchoolDTO schoolDTO;
//getter 和 setter
.....
}
public class SchoolDTO {
@Length(min = 2)
private String schoolName;
//getter 和 setter
.....
}
schoolName这个成员变量打上需要校验的注解,schoolDTO这个成员变量需要打上@Valid注解
2.3自定义注解对参数进行校验
在一些特定业务中,普通注解不能够满足特定参数的校验,那么就需要自定义一些注解来对参数进行校验。
在app中创建账户需要确认密码,这个过程就需要对两次密码进行校验,这时候就需要自定义一个注解去校验这个两个密码是否一致。实现这个自定义注解的方式主要有两步
2.3.1 创建一个注解
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PasswordEqualsValidation.class)
public @interface PasswordEquals {
String message() default "两次密码不一致";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@Documented表示该注解中的注释会被写入文档中
@Target(ElementType.TYPE)表示该注解作用在类、接口或枚举上
@Retention(RetentionPolicy.RUNTIME)表示该注解在运行时任然保留
@Constraint(validatedBy = PasswordEqualsValidation.class)是表示该注解关联PasswordEqualsValidation这个类
message是该注解中的成员
2.3.2 实现ConstraintValidator接口
public class PasswordEqualsValidation implements ConstraintValidator<PasswordEquals, PersonDTO> {
@Override
public boolean isValid(PersonDTO personDTO, ConstraintValidatorContext constraintValidatorContext) {
String password1 = personDTO.getPassword1();
String password2 = personDTO.getPassword2();
boolean flag = false;
if(password1 != null && password2 != null && password1.equals(password2)){
flag = true;
}
return flag;
}
}
创建PasswordEqualsValidation去实现 ConstraintValidator接口,然后重写isValid方法,对密码进行校验,最后和PasswordEquals 注解关联,使得注解具有作用。
ConstraintValidator接口后面有两个参数要填,第一个是要关联的参数,第二个参数是注解要打在哪个地方上,这个地方所对应的类型。
import lombok.*;
import org.hibernate.validator.constraints.Length;
@Setter
@Getter
@PasswordEquals
public class PersonDTO {
@Length(max = 5)
private String name;
private Integer age;
private String password1;
private String password2;
}
因为这里是把注解打在PersonDTO 上,所以第二个参数就是PersonDTO 。
重写的isValid方法就是对密码进行验证是否符合要求
总结
参数校验还是比较重要的一块,初期如果能够将这一块内容处理好,将会节省非常多的时间和精力。