自定义注解校验参数

应用场景:实际开发中,前端给后端传入的Dto中一般有庞大的字段,后台如果挨个写if else去校验这些字段难免会产生大量冗余代码 用自定义注解很方便 用法关键点如下:

package cn.com.goldwind.ercp.fas.persistence.entity.programe.fasAnnotation;

import cn.com.goldwind.ercp.fas.persistence.entity.programe.FasCheckDto;

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;

/**
 * @Author: wuyf
 * @Description: 校验注解
 * @Date:Created in 15:39 2021/11/1
 */
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = FasCheckDto.class)
public @interface FasCheckApplyNotice {
    String message()default "参数有误";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
}

第一步:自定义注解(可以直接复制代码 改个名字就能用)

首先new一个注解(注解其实属于一个类 直接放在类下面的包即可)

引入元注解(即在注解上面标注的注解,如上述代码所示 一共4个),规范注解作用

@Target 这个代表注解生效位置 必填。

@Retention 代表生效阶段 一般都是运行时

@Documented 用javaDoc生成API文档时,是否将该注解记录到API文档中

@Inherited 我也不是很清楚我们的注解是否需要被子类继承。是发生在子类和父类之间的一种注解。
当我们的注解作用域是Element.TYPE时,我们定义在类上的注解可以被子类继承。但是如果我们注解的作用域是Element.METHOD时,并且父类的该方法被子类重写,那作用在父类的注解不会被子类继承。所以如果我们在接口的方法中定义的注解,永远不会被实现类继承,因为实现类一定会重写接口中的方法

注意:@Constraint(validatedBy = FasCheckDto.class)这个注解 代表注解具体指向的是哪个校验类 我们的校验逻辑 都在这个类中实现

message是该注解校验失败时的提示信息,default是默认值,我们可以重写该提示信息(下面有讲)。下面两行代码是自定义注解需要加上的,这里用不到,但是必须有。

package cn.com.goldwind.ercp.fas.persistence.entity.programe;

import cn.com.goldwind.ercp.fas.persistence.entity.programe.fasAnnotation.FasCheckApplyNotice;
import org.apache.commons.collections.CollectionUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Collection;

/**
 * @Author: wuyf
 * @Description: 校验注解类
 * @Date:Created in 15:45 2021/11/1
 */
public class FasCheckDto implements ConstraintValidator<FasCheckApplyNotice, Object> {
    @Override
    public void initialize(FasCheckApplyNotice fasCheckApplyNotice) {

    }

    @Override
    public boolean isValid(Object param, ConstraintValidatorContext constraintValidatorContext) {
        if (param instanceof String) {
            return param != null && !"".equals(param);
        } else if (param instanceof Integer) {
            return param != null;
        } else if (param instanceof Collection) {
            return CollectionUtils.isNotEmpty((Collection) param);
        }
        return false;
    }
}

第二步:自定义注解校验类(直接复制 更改校验逻辑既可以)

new一个校验类,一定要实现ConstraintValidator接口,并且重写接口中的两个方法(我们的校验逻辑就是靠这步) 这个接口是有泛型的,第一个泛型代表了我们这个校验类是哪个注解的校验类(就是第一步建的那个自定义注解),第二个泛型代表该注解校验的参数是什么类型,第二个注解默认是Object类型,

initialize方法是该校验类的初始化方法,在这个方法里,我们可以对传进来的参数作一些处理。
isValid方法就是注解类型的核心校验方法,校验通过与否就是看该方法的返回值是true还是false,true就代表校验通过,false就代表校验失败

上述方法我主要校验了String,Integer,List类型不能为空 

第三步:在类中引入该注解,用法如下:

 这里后面的message就是校验失败后需要的提示信息

第四步:规范提示信息

主要三点:1、在参数类中加入@valid 它的作用就是让我们的自定义注解类起作用 必须用

2、BindingResult类的作用是当注解校验失败时 我们可以自定义返回结果(一般每个公司都有自己的额返回结果,这时候我们只需要拿到校验失败信息放进去就可以),如果不加的话,校验失败后会直接返回http的400错误码,

3就是获取校验失败信息,就是第二步后面的message.

第五步:测试

本人对自定义注解也不是很精通,仅限于正常开发使用,希望对您有所帮助!

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值