Java Validator封装

296 阅读1分钟

在使用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 }
响应:

image.png