在使用Spring搭建Rest服务器的时候我们经常会遇到需要检验请求体参数的情况。
原始的方式是写很多If-Else用于检验,久而久之这会使代码变得非常冗余,一个好的替代方法是使用Java提供的Validator作检验。
在引入spring-boot-starter-validation依赖之后我们可以这样进行校验。
public JSONObject test(@Validate @RequestBody TestRequest request) {
}
然而这种校验方式只能得到校验是否通过,无法得到校验结果的信息。在校验未通过时会直接返回400BadRequest。要想得到校验结果我们需要封装一次Validator。具体封装如下:
public class BeanValidationUtil {
public static final Validator validator = Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory().getValidator();
public static <T> BeanValidationResult validate(T request) {
Set<ConstraintViolation<T>> validate = validator.validate(request);
Iterator<ConstraintViolation<T>> iterator = validate.iterator();
if(iterator.hasNext()) {
ConstraintViolation<T> next = iterator.next();
return BeanValidationResult.fail(next.getMessage());
}
else {
return BeanValidationResult.success("Success");
}
}
}
第一步是通过ValidationFactory生成Validator。其中通过了HibernateValidator配置了failFast,即检验到一个Violation就停止检验。
第二步是调用validator.validate()获取检验结果,并且获取它的Iterator用于判断是否有Violation,如果有的话取下一个Violation的Message(Message在注解中配置)。这样我们就可以得到校验未通过的Message返回Controller了。
补充:
TestController.java
public class TestController {
@PostMapping(name = "Test",value = "/api/test")
public Response<JSONObject> test(@RequestBody TestRequest request) {
JSONObject result = new JSONObject();
BeanValidationResult validationResult = BeanValidationUtil.validate(request);
if(validationResult.getStatus()) {
result.put("request",request);
return Response.success(result);
}else {
log.info("Wrong Params:"+validationResult.getMessage());
return Response.fail(validationResult.getMessage());
}
}
}
TestRequest.java
package com.example.demo.Domain;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
public class TestRequest {
@NotNull(message = "ID不能为空!")
public Integer id;
@NotBlank(message = "Name不能为空!")
public String name;
@Null(message = "Extra必须为空!")
public String extra;
}
测试结果:
发送请求:
{ "id":2 }
响应: