简介

隔离在家工作,最近遇到一个挺好玩的需求哈哈哈。在参数校验前需要做一段逻辑上的处理。比如:同一个接口的参数校验,一个实体类有10个属性满足条件A就校验其中的5个属性,满足条件B就校验另外5个属性。

常用的处理逻辑

一般我们在做Spring Boot项目时候的参数校验都是直接通过在接口入口处增加@Valid,然后Spring在序列化参数的时候就回自动帮我们进行校验。

实体类增加校验注解

这里举例:@NotBlank

public class Store{
    private Integer id;
    /**
     * 名称
     */
    @NotBlank(message = "name不能为空")
    private String name;
}

接口增加校验注解

增加@Valid参数校验注解

@PostMapping("/store")
public String add(@RequestBody @Valid Store store) throws Exception {
    store.setGeom(CoordinatesUtil.buildPoint(store.getLongitude(), store.getLatitude()));
    storeService.save(store);
    return "添加成功,id:" + store.getId();
}

Spring在序列化参数的时候会自动校验Store的Name属性不能为空。

编程调用校验

那么怎么编程调用呢?其实也很简单,大概的实现逻辑是下面的方法,自己创建一个校验器。

package com.unfbx.validtest.test;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class ValidateUtil {
    /**
     * 校验器
     * @param t         参数
     * @param <T>       参数类型
     * @return
     */
    public static <T> List<String> valid(T t){
        Validator validatorFactory = Validation.buildDefaultValidatorFactory().getValidator();
        Set<ConstraintViolation<T>> errors = validatorFactory.validate(t);
        return errors.stream().map(error -> error.getMessage()).collect(Collectors.toList());
    }
}

然后我们写个main方法进行测试

public class ValidTest {

    public static void main(String[] args) {
        Store store = new Store(1, null);
        System.out.println(ValidateUtil.valid(store));
    }
}

输出的信息是错误的信息列表:
输出信息

我们查看Validator的validate方法可以看到其实它的实现方法其实是很丰富的,还可以结合groups参数做到分组校验。除此之外还有其他的几个校验方法,也可以学习下。
分组校验

<T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups);

注意点

Spring boot项目在2.3.0之前的版本是自带校验包的。
但是在2.3.0及以上版本需要手动引入校验包。

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.0.Final</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>