自定义集合类型校验

总结⼀下@Validated和@Valid在嵌套验证功能上的区别:
@Validated:在方法参上无法单独提供嵌套验证功能。不能用在成员属性(字段)上,也无法提示框架进行嵌套验证。能配合嵌套验证注解@Valid进行嵌套验证。
@Valid:用在方法入参上无法单独提供嵌套验证功能。能够用在成员属性(字段)上,提示验证框架进⾏嵌套验证。能配合嵌套验证注解
@Valid进⾏嵌套验证。使用@Valid需要配合BindingResult可以直接提供参数验证结果

基于@Validated不能用在属性上或字段上所以不能进行集合嵌套验证及@Valid需要使用BindingResult才能显示验证结果且不能进行分组验证;所以本文通过自定义注解结合@Validated实现集合验证时分组及嵌套验证。

1、自定义一个校验注解类

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 顶一个一个集合中每一个元素校验
 */
@Retention(RetentionPolicy.RUNTIME)
/**
 *
 */
@Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Constraint(validatedBy = {CollectionValidator.class})//指定使用那些类型进行校验
public @interface CollectionAny {
    //定义默认验证消息
    String message() default "集合验证不通过";

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

    Class<? extends Payload>[] payload() default {};
}

2、自定义一个校验处理类



import com.ruoyi.common.utils.bean.BeanValidators;
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorContextImpl;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.util.Collection;
import java.util.Set;

/**
 * 定义一个结合校验器
 * 第一个参数“CollectionAny”定义校验注解的类
 * 第二个参数“Collection”指定要校验的参数类型
 */
public class CollectionAnyValidator implements ConstraintValidator<CollectionAny, Collection> {
    @Autowired
    protected Validator validator;

    /**
     * 這个方法要返回“true”和“false”
     * true:表示验证通过
     * false:表示验证不通过,明确返回false的时候才会提示对应配置的消息
     *
     * @param collection
     * @param constraintValidatorContext
     * @return
     */
    @Override
    public boolean isValid(Collection collection, ConstraintValidatorContext constraintValidatorContext) {
        if (collection == null || collection.size() == 0) {
            return true;
        }
        try {

            ConstraintValidatorContextImpl constraintValidatorContext1 = (ConstraintValidatorContextImpl) constraintValidatorContext;
            Class<?>[] groupArray = null;
            if (constraintValidatorContext1 != null) {
                Set<Class<?>> groupSet = constraintValidatorContext1.getConstraintDescriptor().getGroups();
                groupArray = groupSet.toArray(new Class<?>[0]);
            }
            for (Object bean : collection) {
                //groupArray 让验证继续传递分组特性
                BeanValidators.validateWithException(validator, bean, groupArray);
            }
            return true;
        } catch (ConstraintViolationException ex) {
            //禁用默认约束信息
            constraintValidatorContext.disableDefaultConstraintViolation();
            //将默认信息与具体对象错误信息合并成新的模板
            constraintValidatorContext.buildConstraintViolationWithTemplate(String.format("%s[%s]", constraintValidatorContext.getDefaultConstraintMessageTemplate(), ex.getMessage()))
                    //必须要使用该方法将消息添加到认证器中
                    .addConstraintViolation();
            return false;
        }
    }
}

3、测试验证实体类


import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Update;

import javax.validation.constraints.NotNull;

public class TestEntity {
    @NotNull(message = "nameInsert不能为空", groups = Insert.class)
    public String nameInsert;
    @NotNull(message = "nameUpdate不能为空", groups = Update.class)
    public String nameUpdate;
    @NotNull(message = "name不能为空")
    public String name;
}

4、测试验证集合类


import com.ruoyi.common.collection.CollectionAny;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public class TestEntityColleection {

    @CollectionAny(message = "listInsert字段集合验证不通过", groups = Insert.class)
    public List<TestEntity> listInsert;

    @CollectionAny(message = "listUpdate字段集合验证不通过", groups = Update.class)
    public List<TestEntity> listUpdate;

    @CollectionAny(message = "字段集合验证不通过")
    public List<TestEntity> list;

}

5、验证方法和参数

    //{
    //    "list": [
    //        {
    //            "name": "",
    //            "nameInsert": null,
    //            "nameUpdate": null
    //        }
    //    ],
    //    "listInsert": [
    //        {
    //            "name": null,
    //            "nameInsert": null,
    //            "nameUpdate": null
    //        }
    //    ],
    //    "listUpdate": [
    //        {
    //            "name": null,
    //            "nameInsert": null,
    //            "nameUpdate": null
    //        }
    //    ]
    //}
    @ApiOperation("没有分组")
    @PostMapping("/test2")
    public AjaxResult test2(@RequestBody @Validated TestEntityColleection testEntity) {
        return AjaxResult.success();
    }

    //{
    //    "list": [
    //        {
    //            "name": null,
    //            "nameInsert": null,
    //            "nameUpdate": null
    //        }
    //    ],
    //    "listInsert": [
    //        {
    //            "name": null,
    //            "nameInsert": "",
    //            "nameUpdate": null
    //        }
    //    ],
    //    "listUpdate": [
    //        {
    //            "name": null,
    //            "nameInsert": null,
    //            "nameUpdate": null
    //        }
    //    ]
    //}
    @ApiOperation("Update分组")
    @PostMapping("/testUpdate")
    public AjaxResult testUpdate(@RequestBody @Validated(Update.class) TestEntityColleection testEntity) {
        return AjaxResult.success();
    }

    //{
    //    "list": [
    //        {
    //            "name": null, 
    //            "nameInsert": null, 
    //            "nameUpdate": null
    //        }
    //    ], 
    //    "listInsert": [
    //        {
    //            "name": null, 
    //            "nameInsert": null, 
    //            "nameUpdate": null
    //        }
    //    ], 
    //    "listUpdate": [
    //        {
    //            "name": null, 
    //            "nameInsert": null, 
    //            "nameUpdate": ""
    //        }
    //    ]
    //}
    @ApiOperation("Insert分组")
    @PostMapping("/testInsert")
    public AjaxResult testInsert(@RequestBody @Validated(Insert.class) TestEntityColleection testEntity) {
        return AjaxResult.success();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值