该篇只介绍关于对一个实体类内字段属性做参数校验。
因为我个人觉得加入拦截器AOP那种校验和直接对controller添加@Validated的这些方式,其实很多老项目是无法融入的,涉及到架构变改了。
而对一个实体类内字段属性做参数校验这种方式,是可以不动项目架构去扩展参数校验的。
OK,我们开始编码。
对于springboot项目,hibernate-validator 的使用虽然有专属的jar包依赖:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.17.Final</version> </dependency>
但是在springboot的web包里也包含了这个jar,所以一般是不需要额外导入依赖的:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
创建一个TestParams.java,这个类是用于接口接收参数的:
import lombok.Data; import org.hibernate.validator.constraints.Range; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Pattern; /** * @Author : JCccc * @CreateTime : 2019/10/15 * @Description : **/ @Data public class TestParams { @NotBlank(message = "用户名不能为空") private String userName; @NotBlank(message = "密码不能为空") private String password; @NotBlank(message = "真实姓名不能为空") private String realName; @Range(min = 0, max = 99, message = "年龄应该在0到99之间") private Integer age; @Pattern(regexp = "男|女", message = "必须是男或女") private String sex; @Pattern(regexp = "\\d{3}-\\d{8}|\\d{4}-\\d{7}|\\d{11}", message = "号码不正确") private String telephone; }
PS: 这个类我用到了lombok,可以省掉很多代码,set/get /toString等等,没使用过的可以去了解下。
lombok依赖:
<!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> <scope>provided</scope> </dependency>
然后是测试接口,
@PostMapping(value = "/testValidatorPost") public String testValidatorPost(@Valid @RequestBody TestParams testParams) { return "参数校验通过:"+ testParams.toString(); }
调用这个post接口,故意传入不符合规则的参数:
返回情况是:
这种情形,是因为在进入接口里面的逻辑前,开始了对这个testParams类参数的校验 ,校验不通过,所以直接返回400了,并且返回来很多信息,包括我们自己写的message。
但是,显然这种返回信息场景是不太能让人接受的,所以我们对这个接口稍作修改:
@PostMapping(value = "/testValidatorPost") public String testValidatorPost(@Valid @RequestBody TestParams testParams, BindingResult result) { if (result.hasErrors()) { StringBuffer errorMessage = new StringBuffer("参数校验有误:"); for (ObjectError error : result.getAllErrors()) { errorMessage = errorMessage.append(error.getDefaultMessage()).append(";"); } System.out.println(errorMessage); return String.valueOf(errorMessage); } return "参数校验通过:" + testParams.toString(); }
加上了BindingResult,并对errors进行逻辑处理,报错的时候也就是校验不通过时,我们进行逻辑处理。
再次调用接口(这里只是示例,我们可以将捕抓出来的message自行处理即可):
同样,Get请求也一样,如果是使用类接收,还是很方便的,效果是一样的:
@GetMapping(value = "/testValidatorGet") public String testValidatorGet(@Valid TestParams testParams, BindingResult result) { if (result.hasErrors()) { StringBuffer errorMessage = new StringBuffer("参数校验有误:"); for (ObjectError error : result.getAllErrors()) { errorMessage = errorMessage.append(error.getDefaultMessage()).append(";"); } System.out.println( errorMessage ); return String.valueOf(errorMessage); } return "参数校验通过:" + testParams.toString(); }
OK,到此。