@Valid不生效:基于@Valid校验工具类

        很多时候我们都需对api的参数进行规则检验,校验,如不能为空,长度限制,电话号码等等。一般我都使用validation的@Valid注解,再在相应的参数上加上如@NotBlank之类的注解来实现校验,但是在一些特殊的场景下@Valid注解不会生效,也就不会对参数校验,比如service接口我需要校验,所以基于validation封装了如下工具类。其中用到的EmptyChecker工具类见:  java常用判空工具类_百块富翁的博客-CSDN博客_java判空工具类


import com.alibaba.fastjson.JSON;
import org.hibernate.validator.HibernateValidator;

import javax.validation.*;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

/**
 * @ClassName 自定义参数校验器
 * @Description 在service层Validator的@Valid注解无法生效,使用以下方法可以对Validation的相关注解生效,如@NotNull
 * 如果对象内包含对象,下层对象仍需校验,请使用 @Valid 标识
 * 注意:目前不支持内部类
 * @Author miss you BUG
 * @Date 2021/8/12 16:11
 * @Email [email protected]
 */
public class ValidUtil {

  //初始化检查器。
    static ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
            .configure()
            .failFast(false)
            .buildValidatorFactory();
    static Validator validator = validatorFactory.getValidator();

    public static void validChecker(Object object) {
        List> result = new ArrayList<>();
        serviceValid(object, result);
        if (EmptyChecker.notEmpty(result)) {
            throw new RuntimeException(JSON.toJSONString(result));
        }
    }

    private static void serviceValid(Object object, List> result) {
        try {
            LinkedHashMap msg = new LinkedHashMap<>();
   
            //检查object
            Set> set = validator.validate(object);
            List list = new ArrayList<>();
            //循环set,获取检查结果
            for (ConstraintViolation voset : set) {
                list.add("key:" + voset.getPropertyPath() + ", errMsg:" + voset.getMessage() + ";");
            }
            Class classInfo = object.getClass();
            if (EmptyChecker.notEmpty(list)) {
                msg.put("className", classInfo.getName());
                msg.put("errMsg", list);
                result.add(msg);
            }
            Field[] fields = classInfo.getDeclaredFields();//Object是已经被赋值的对象实例
            for (Field field : fields) {
                Type genericFieldType = field.getGenericType();
                Valid valid = field.getAnnotation(Valid.class);
                //如果存在这个注解
                if (EmptyChecker.notEmpty(valid)) {
                    //如果是List
                    if (genericFieldType instanceof ParameterizedType) {
                        //打开私有访问
                        field.setAccessible(true);
                        //获取属性值
                        Object value = field.get(object);
                        if (EmptyChecker.isEmpty(value)) {
                            LinkedHashMap msg1 = new LinkedHashMap<>();
                            msg1.put("className", field.getName());
                            msg1.put("errMsg", "不能为空!");
                            result.add(msg1);
                            continue;
                        }
                        Collection cloneable = (Collection) value;
                        //拿到List的值
                        for (Object obj : cloneable) {
                            serviceValid(obj, result);
                        }
                    } else {//获取属性值
                        //打开私有访问
                        field.setAccessible(true);
                        Object value = field.get(object);
                        serviceValid(value, result);
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


} 
  

 使用方法:在参数上还是一样的使用@NotNull之类的注解,在服务中手动的调用工具类方法把需校验的参数传进去。

eg:

@Data
public class User{
    @NotNull
    private Integer id;
    @NotBlank
    private String name;
    //下层对象需校验需使用@Valid注解
    @Valid
    private Order order




}
@Data
public class Order{
    @NotNull
    private Long id;
    @NotBlank
    private String code;

}

public class TsetServiceImpl{
    
    public boolean validTest(User user){
            //参数校验
            ValidUtil.validChecker(user);

        return true;
    }


}

        

你可能感兴趣的:(工具类,java,validation,Valid,参数校验)