GroupSequenceProvider动态校验入参;@Validated和@Valid的区别

Posted 好大的月亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GroupSequenceProvider动态校验入参;@Validated和@Valid的区别相关的知识,希望对你有一定的参考价值。

需求场景

平时在controller的入参校验中大多都是单个参数校验
一般都是直接用javax的注解 + javax.validation.Valid注解一把梭。

不过也有场景是需要动态校验。
假设入参的年龄和地区相关。
上海地区的年龄范围需要在10-20
浙江地区的年龄范围需要在10-30

这个时候要么就是直接硬编码了,但是前人肯定遇到过这种问题。

org.hibernate.validator.group.GroupSequenceProvider注解就能帮我们稍微实现的漂亮一点。

如果当前项目中没有对应依赖的话先引入依赖

<dependency>
	<groupId>org.hibernate.validator</groupId>
	<artifactId>hibernate-validator</artifactId>
	<version>6.2.0.Final</version>
</dependency>

代码Demo

自定义编码实现动态校验


package com.xxx.xxx.valid.group;

/**
 * 根据动态条件来决定是否判断 NotNull
 */
public interface NotNullByConditionGroup 





package com.xxx.xxx.xxx;

import com.xxx.xxx.valid.group.NotNullByConditionGroup;
import com.xxx.xxx.valid.ProductAccessoriesSkuQueryProvider;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.group.GroupSequenceProvider;

import javax.validation.constraints.NotNull;
import java.io.Serializable;


@GroupSequenceProvider(ProductAccessoriesSkuQueryProvider.class)
@Data
public class ProductAccessoriesSkuQueryListDTO implements Serializable 

    private static final long serialVersionUID = 8297881653432975830L;

    @ApiModelProperty(value = "产品id")
    @NotNull(message = "产品id不能为空", groups = NotNullByConditionGroup.class)
    private Long productId;

    @ApiModelProperty(value = "颜色id,详情见数据字典 color")
    @NotNull(message = "颜色id不能为空", groups = NotNullByConditionGroup.class)
    private Long colorId;

    @ApiModelProperty(value = "尺寸id,详情见数据字典 sales_size")
    @NotNull(message = "尺寸id不能为空", groups = NotNullByConditionGroup.class)
    private Long sizeId;

    @ApiModelProperty(value = "产品skuId")
    private Long productSkuId;





package com.xxx.xxx.valid;

import com.xxx.xxx.xxx.ProductAccessoriesSkuQueryListDTO;
import com.xxx.xxx.xxx.group.NotNullByConditionGroup;
import org.hibernate.validator.spi.group.DefaultGroupSequenceProvider;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


/**
 * 校验当 productSkuId 不存在的时候 sizeId + productId + colorId 不能为空
 */
public class ProductAccessoriesSkuQueryProvider implements DefaultGroupSequenceProvider<ProductAccessoriesSkuQueryListDTO> 

    @Override
    public List<Class<?>> getValidationGroups(ProductAccessoriesSkuQueryListDTO bean) 
        List<Class<?>> defaultGroupSequence = new ArrayList<>();
        defaultGroupSequence.add(ProductAccessoriesSkuQueryListDTO.class); // 这一步不能省,否则Default分组都不会执行了,会抛错的
        if(Objects.nonNull(bean))
            Long productSkuId = bean.getProductSkuId();

            if(Objects.isNull(productSkuId))
                defaultGroupSequence.add(NotNullByConditionGroup.class);
            

        

        return defaultGroupSequence;
    





@PostMapping("queryList")

public CommonResult<List<? extends xxx>> queryList(@RequestBody @Validated ProductAccessoriesSkuQueryListDTO queryList)
    return CommonResult.success();



@Validated指定分组校验

public class ValidatedGroup 
 
    public interface CREATE
 
    public interface DELET
 
    public interface UPDATE
 
    public interface QUERY




import lombok.Data;
 
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
 
@Data
public class ValidatedVO 
 
    //更新、删除时不能为空
    @NotNull(message = "id不能为空", groups = ValidatedGroup.UPDATE.class, ValidatedGroup.DELET.class)
    private Long id;
 
    //新增、更新时不能为空
    @NotBlank(message = "name不能为空", groups = ValidatedGroup.CREATE.class ,ValidatedGroup.UPDATE.class)
    private String name;
 
    //查询时不能为空
    @NotBlank(message = "queryParam不能为空", groups = ValidatedGroup.QUERY.class)
    private String queryParam;
 





public ValidatedVO bindValidate(@RequestBody @Validated(value= ValidatedGroup.DELET.class) ValidatedVO validatedVO/*, BindingResult result*/) 
    return validatedVO;

@Validated和@Valid的区别

在校验的时候会发现有2个很类似的注解,@Valid和@Validated
首先这两个的包都是不同的
javax.validation.Valid
org.springframework.validation.annotation.Validated

其次
@Valid:标准JSR-303规范的标记型注解,用来标记验证属性和方法返回值,进行级联和递归校验
@Valid可以用在属性级别约束,用来表示级联校验。
@Valid可用于方法、字段、构造器和参数上

@ValidatedSpring的注解,是标准JSR-303的一个变种(补充),提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制。上面提到的分组校验就是利用了其分组功能
@Validated注解可以用于类级别,用于支持Spring进行方法级别的参数校验。
@Validated只能用在类、方法和参数上;

以上是关于GroupSequenceProvider动态校验入参;@Validated和@Valid的区别的主要内容,如果未能解决你的问题,请参考以下文章

springBoot参数联合校验,自定义分组校验

vue项目动态添加表单和校验

vue+element动态校验自定义校验规则实时校验

表单多个表单项的动态校验总结

解决uview下表单无法动态校验的问题

如何在js校验完成后动态修改 placeholder?