使用@Constraint配合自定义注解开发

5 篇文章 0 订阅
1 篇文章 0 订阅

前言

通常我们在开发的过程中,需要对前端传入的数据进行校验,尽管这一步已经在前端进行了一次校验,虽然现在已经有了很多校验的注解,@NotNull、@NotBlank、@URL等一系列注解帮助我们进行校验,但是在实际的业务开发过程中,这些可能不足以满足我们的需求,这时候我们就需要自己来定义注解了。

可能需要用到的依赖按需导入:

		<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.4.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.logging</groupId>
            <artifactId>jboss-logging</artifactId>
            <version>3.3.0.Final</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml</groupId>
            <artifactId>classmate</artifactId>
            <version>1.3.3</version>
        </dependency>

@Constraint

这个注解的主要作用就是帮助我们来处理验证逻辑的,根据根据自己的业务需求来完成这一块验证的逻辑。下面我们就来简单测试一下。

**场景 **:假设我们一个实体类的属性如下解释,我们需要对前端传入的数字是不是0或1。

/**
     * 显示状态[0-不显示;1-显示]
     */
    private Integer showStatus;

定义注解

@Documented
@Constraint(validatedBy = {ListValueConstraintValidator.class})
@Target({ElementType.METHOD,ElementType.FIELD,ElementType.ANNOTATION_TYPE,ElementType.CONSTRUCTOR,ElementType.PARAMETER,ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ListValue {
   
    String message() default "{com.atguigu.common.valid.ListValue.message}";

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

    
}

message():错误信息,如果我们没有在注解中定义错误信息的话,他会默认去寻找com.atguigu.common.valid.ListValue.message为key的错误信息
groups():这个主要是来进行分组验证的。
** vals() ** :自行定义的值

我们可以看到@Constraint中
@Constraint(validatedBy = {ListValueConstraintValidator.class})
这段意思是我们将此注解的验证逻辑交给ListValueConstraintValidator来处理,这里是一个数组,我们可以传入多个处理逻辑。

ConstraintValidator接口,它有两个泛型,第一个是自定义的注解类,第二个就是要验证的数据的类型,这两个类里面都有两个方法,initialize和isValid,第一个是初始化方法,第二个是验证的逻辑方法,返回true,则验证通过,否则则不通过。

ListValueConstraintValidator自定义验证逻辑

public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {

    private Set<Integer> set = new HashSet<>();
    /**
     * 初始化 加载注解的信息。也就是带有此注解Bean上的vals值
     * @param constraintAnnotation
     */
    @Override
    public void initialize(ListValue constraintAnnotation) {
        int[] vals = constraintAnnotation.vals();
        for (int val : vals) {
            set.add(val);
        }
    }

    /**
     * 判断是否校验成功
     * @param value 需要校验的值 实际传入的值
     * @param context 上下文信息
     * @return
     */
    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {

        return set.contains(value);
    }
}

** ValidationMessages.properties **

规范(JSR303)说,我必须将ValidationMessages.properties放到我的类路径根目录中,我希望它应该是MyDeploymentUnit.war / WEB-INF / classes / ValidationMessages.properties,这就是我的应用程序的构建和部署方式。出于调试原因,我将此代码添加到了自定义验证器中,以确保文件存在并正确设置。

在这里插入图片描述
key就是我们在注解定义的默认 message的值。

测试

在Controller中需要进行校验的Bean加上 ** @Validated ** 注解
在这里插入图片描述

需要验证的 属性
在这里插入图片描述
这里的如果校验不通过的话,他会抛出一个异常,我们只需要捕获到这个错误信息即可。
在这里插入图片描述

如果我们去掉属性声明的message信息 他会去寻找默认的ValidationMessages.properties下的信息。

在这里插入图片描述

分组校验

可能大家会注意到我在Controller中使用 @Validated 注解时会带有一个value值,他的作用是对操作进行分组。比如请看如下

	@NotNull(message = "修改商品时请传入商品id",groups = {UpdateGroup.class})
    @Null(groups = {AddGroup.class},message = "不能指定id")
    @TableId
    private Long brandId;

商品的数据表的对应的ID,我们可能在进行新增操作时无需我们来指定对应的ID,因为我们一般设置都会默认自增的。而我们在查询或者更新的时候可能会根据ID来查出这一条记录。总的来说的就是在进行更新时需要ID,新增不需要。每一个注解都会带有groups这个属性来声明自己的组。

如何使用呢?
很简单:

定义对应的接口或者类。

public interface AddGroup {
}
// ------------------------------
public interface UpdateGroup {
}
//---------------------------------
public interface UpdateStatusGroup {
}

我们只需要定义三个接口来声明组,无需任何操作。

在Controller中的@Validated 注解中声明对那个组进行验证。

@RequestMapping("/save")
    public R save(@Validated(value = {AddGroup.class}) @RequestBody BrandEntity brand) {
        brandService.save(brand);
        return R.ok();
    }

实体类进行分组逻辑

	@NotNull(message = "修改商品时请传入商品id",groups = {UpdateGroup.class})
    @Null(groups = {AddGroup.class},message = "不能指定id")
    @TableId
    private Long brandId;

验证: 新增时:传入ID会失败
在这里插入图片描述

更新时:不传ID 会失败
在这里插入图片描述

  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈橙橙丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值