自定义注解校验参数"/>
自定义注解校验参数
应用场景:实际开发中,前端给后端传入的Dto中一般有庞大的字段,后台如果挨个写if else去校验这些字段难免会产生大量冗余代码 用自定义注解很方便 用法关键点如下:
package cn.goldwind.ercp.fas.persistence.entity.programe.fasAnnotation;import cn.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.goldwind.ercp.fas.persistence.entity.programe;import cn.goldwind.ercp.fas.persistence.entity.programe.fasAnnotation.FasCheckApplyNotice;
import org.apachemons.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> {@Overridepublic void initialize(FasCheckApplyNotice fasCheckApplyNotice) {}@Overridepublic 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.
第五步:测试
本人对自定义注解也不是很精通,仅限于正常开发使用,希望对您有所帮助!
更多推荐
自定义注解校验参数
发布评论