首页 > 其他分享 >hibernate-validator 参数校验2(补充)

hibernate-validator 参数校验2(补充)

时间:2022-10-29 17:47:18浏览次数:129  
标签:hibernate 校验 param validator import 注解 Validated class

目录

基础:SpringBoot各种参数效验

hibernate-validator 参数校验1

资料参考地址1: spring中@Validated注解的使用

一 @Validated分组校验(单层对象)

@Valid不提供分组的功能

由于在项目中存在几个接口共用一个实体类,在不同的接口中某些字段的规则是不一样的,如果想要用同一个对象的话,这个时候就需要用到分组的功能了,指定字段在某个组别下的规则。

不指定分组,只校验默认的组别Default,导包import javax.validation.groups.Default;

1.1 分组校验测试参数

@Data
@Accessors(chain = true)
public class GroupParam {
    @NotBlank(message = "更新组不能为空", groups = {UpdateGroup.class})
    private String updateValue;
    @NotBlank(message = "默认组不能为空")
    private String defaultValue;
    @NotBlank(message = "添加组不能为空", groups = {AddGroup.class})
    private String addValue;
    @NotBlank(message = "自定义分组组不能为空", groups = {CustomGroup.class})
    private String customValue;
    private Boolean status;
}

1.2 分组接口

public interface AddGroup {
}
public interface UpdateGroup {
}
public interface CustomGroup {
}

1.3 controller测试接口

    /**
     * 不指定分组,只校验默认的组别Default
     * @param param
     * @return
     */
    @PostMapping("/default")
    public String defaultGroup(@Validated @RequestBody GroupParam param) {
        return "Validated注解默认成功!";
    }

    /**
     *  测试分组校验(新建)
     *  指定组别校验,校验自定义的AddGroup组别
     * @param param 参数
     * @return
     */
    @PostMapping("/add")
    public String groupAdd(@Validated({AddGroup.class}) @RequestBody GroupParam param) {
        log.info(param.toString());
        return "Validated注解默认成功!";
    }

    /**
     * 测试分组校验(更新)
     * 指定组别校验,校验自定义的UpdateGroup组别和默认的组别Default
     * @param param 参数
     * @return
     */
    @PostMapping("/update")
    public String groupUpdate(@Validated({UpdateGroup.class,Default.class}) @RequestBody GroupParam param) {
        log.info(param.toString());
        return "Validated注解默认成功!";
    }

二 @Validated根据前端的传参状态进行校验(单层对象)

@Validated根据前端的传参状态,添加不同的组别,最后进行手动校验(单层对象)

2.1 controller测试接口

    /**
     * 框架先校验AddGroup组别的参数,然后如果状态是类别2,则需要手动添加要
     校验CustomGroup和Default组别,最后再调用校验的工具类
     *
     * @param param
     * @return
     */
    @PostMapping("/manual")
    public String manualGroup(@Validated({AddGroup.class}) @RequestBody GroupParam param) throws Exception {
        List<Class> groupClasses = new ArrayList<>();
        if (Boolean.TRUE.equals(param.getStatus())) {
            groupClasses.add(CustomGroup.class);
            groupClasses.add(Default.class);
        }
        //转成数组
        Class[] groups = groupClasses.toArray(new Class[0]);
        //手动调用校验的方法
        ValidatorUtils.validateEntity(param, groups);
        return "Validated注解手动添加成功!";
    }

2.2 手动校验工具类

import lombok.extern.slf4j.Slf4j;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;

@Slf4j
public class ValidatorUtils {
    private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    /**
     * 手动校验
     *
     * @param object
     * @param groups
     * @throws Exception
     */
    public static void validateEntity(Object object, Class<?>... groups) throws Exception {
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
        if (!constraintViolations.isEmpty()) {
            StringBuilder errorMsg = new StringBuilder();
            for (ConstraintViolation<?> e : constraintViolations) {
                errorMsg.append(e.getMessage() + ";");
            }
            throw new Exception(errorMsg.substring(0, errorMsg.toString().length() - 1));
        }
    }
}

三 @Validated自定义注解校验

如果框架提供的注解不满足实际开发中业务的校验,可以自定义一个校验注解来实现

3.1自定义一个注解

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
 * 自定义注解
 * @author lyn
 */
@Target({ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RUNTIME)
@Documented
//此处指定了该注解的实现类为ListNotHasNullValidatorImpl
@Constraint(validatedBy = ListNotHasNullValidatorImpl.class)
//在同一个地方使用相同的注解会报错,所以该注解是装同一个注解的容器,
@Repeatable(ListNotHasNull.List.class)
public @interface ListNotHasNull {

    /**
     * 添加value属性,可以作为校验时的条件,若不需要,可去掉此处定义
     */
    int value() default 0;

    /**
     * 默认的报错提示信息
     *
     * @return
     */
    String message() default "List集合中的元素不能含有null元素";

    Class<?>[] groups() default {};

    /**
     * 约束注解的有效负载  将一些元数据信息与该约束注解相关联
     *
     * @return
     */
    Class<? extends Payload>[] payload() default {};

    /**
     * 定义List,为了让Bean的一个属性上可以添加多套规则
     */
    @Target({METHOD, FIELD, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Documented
    @interface List {
        ListNotHasNull[] value();
    }

}

3.2 实现ConstraintValidator接口

使用泛型会报错,只能使用固定对象

待解决

import lombok.SneakyThrows;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Component;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;

/**
 * 自定义注解的具体校验规则实现
 * 集合不能为空,并且对象里面的属性值也不能为空
 *
 * @author lyn
 */
@Component
public class ListNotHasNullValidatorImpl implements ConstraintValidator<ListNotHasNull, List<User>> {
    private int value;

    @Override
    public void initialize(ListNotHasNull constraintAnnotation) {
        //传入value 值,可以在校验中使用
        this.value = constraintAnnotation.value();
    }

    /**
     * 返回false就会抛出错误的信息
     * @param list
     * @param constraintValidatorContext
     * @return
     */
    @SneakyThrows
    @Override
    public boolean isValid(List<User> list, ConstraintValidatorContext constraintValidatorContext) {
        if (list == null || list.size() == 0) {
            return false;
        }
        for (User obj : list) {
            Class<?> clazz = obj.getClass();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {

                Class<?> type = field.getType();
                // 设置些属性是可以访问的
                boolean isStatic = Modifier.isStatic(field.getModifiers());
                if (isStatic) {
                    continue;
                }
                // 设置些属性是可以访问的
                field.setAccessible(true);
                // 得到此属性的值
                Object val = field.get(obj);
                if (val == null) {
                    return false;
                }

            }
        }
        return true;
    }
}

3.3 controller接口

    /**
     * 自定义注解测试
     * @param company 参数
     * @return
     */
    @PostMapping("/defined")
    public String definedAdd(@Validated(value = {AddGroup.class}) @RequestBody Company company) {
        return "自定义注解添加成功!";
    }

3.4 实体类

@Data
public class Company {
    @ListNotHasNull(message = "集合不能为空,并且对象里面的属性值也不能为空", groups = {AddGroup.class})
    private List<User> users;
}
@Data
public class User {
    private String name;
    private Integer age;
    private String address;
}

四、@Validated和@Valid的不同

  1. @Valid用来标记验证属性和方法返回值,支持进行级联和递归校验(可以结合@Validated注解在嵌套对象中使用)。
  2. @Validated是Spring提供的注解,提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制。
  3. 在Controller中校验方法参数时,使用@Valid和@Validated并无特殊差异(若不需要分组校验的话)。
  4. @Validated只能用在类、方法和参数上,而@Valid可用于类、方法、字段、构造器和参数上。
  5. 他们的所属的包不同,@Validated属于spring,而@Valid属于javax。
  • @Validated :org.springframework.validation.annotation.Validated
  • @Valid:javax.validation.Valid

总结:

建议直接用@Validated,功能比@Valid注解强大

标签:hibernate,校验,param,validator,import,注解,Validated,class
From: https://www.cnblogs.com/lyn8100/p/16837200.html

相关文章

  • Hibernate,JPA 对象关系映射之关联关系映射策略
    关联关系映射关联关系映射,是映射关系中比较复杂的一种映射关系,总的说来有一对一、一对多和多对多几种关系。细分起来他们又有单向和双向之分。下面我们逐一介绍一下。单向O......
  • element-ui表单自定义校验
    1.问题描述项目开发过程中,遇到表单校验,这次的校验规则比较严,element-ui表单自带的校验完全解决不了问题。2.解决方法使用element-ui 表单校验中的......
  • CRC循环冗余校验码
    CRC的编码方法是:在k位信息码之后拼接r位校验码;多项式为G(X)=Xn+X+1,信息码是xxxxx,计算CRC校验码,n代表从右边数起的第几位(就是2的几次方)。1多项式化解成二进制数2信息码末......
  • javascript校验mac和ip
     1.校验mac:functionisValidMAC(mac){varreg=/^[A-Fa-f\d]{2}:[A-Fa-f\d]{2}:[A-Fa-f\d]{2}:[A-Fa-f\d]{2}:[A-Fa-f\d]{2}:[A-Fa-f\d]{2}$/;returnreg.......
  • 使用 JSTL 报错:javax/servlet/jsp/tagext/TagLibraryValidator
    jsp使用jstl,访问页面之后报错,如上图所示。我的Tomcat版本是10.0,导入的jstl是javax.servlet下的,应该导入以下几个包:<dependency><groupId>mysql</groupId>......
  • python校验各国手机号格式是否正确
    下载库phonenumbersgithub地址defverify_phone_number(phone_number:str)->(bool,int):"""校验各国手机号格式"""z=phonenumbers.parse(ph......
  • hibernate的OneToMany映射
    hibernate的OneToMany和ManyToOne映射1、前言在数据库中,不管一对多或者多对一都统称为:一对多。@OneToMany和@ManyToOne指定了一对多的关系。2、@OneToMany使用外键映射......
  • NHibernate 1.0 Released 版本发布了
    NHibernateisaportofHibernatetothe.NETplatform.Hibernateistheleadingopen-sourceobject-relationalpersistencelibraryforJava,usedtopersistpla......
  • 《上海悠悠接口自动化平台》-2.extract 提取结果与validate 校验结果
    前言当接口请求成功后,返回的内容,我们需要提取内容,并校验实际结果与预期结果是否一致。平台可以支持3种方式提取结果1.body.key方式根据属性点的方式提取,或者下标取值b......
  • Hibernate缓存及核心接口类详解
    Hibernate缓存概述一级缓存(session级别缓存)也叫事务级别的缓存二级缓存(sessionFactory缓存)也叫应用级缓存三级缓存(查询缓存)区别:一级缓存的生命周期和session的生命......