自定义注解使用

现象:

自定义注解使用

方法:

1:元注解
java.lang.annotation 下定义了元注解

  • @Documented 文档相关 标注了此注解则会包含在javadoc文档中
  • @Retention 指定注解生命周期
  • @Target 指定注解作用范围
  • @Inherited 指定子类可以继承父类的注解
  • @Native 指定字段是常量
  • @Repeatable 指定在一个地方可以重复使用同一个注解

2:元注解 @Retention 生命周期

  • SOURCE: 只保留在源文件
  • CLASS: 保留到class文件
  • RUNTIME: 运行时也存在

3:元注解 @Target 作用范围

  • TYPE——接口、类、枚举、注解
  • FIELD——字段、枚举的常量
  • METHOD——方法
  • PARAMETER——方法参数
  • CONSTRUCTOR ——构造函数
  • LOCAL_VARIABLE——局部变量
  • ANNOTATION_TYPE——注解
  • PACKAGE——包,用于记录java文件的package信息

4:新建java类选择注解@Annitation

在这里插入图片描述

5:示例建立MyAnnitation注解

在这里插入图片描述
6:使用:
在这里插入图片描述

二:实例使用:

需求:自定义注解校验请求参数只能是指定值
比如 请求接口 type 参数 只能是"1"、“2”、“3”

方法:
1:引入validation校验jar包

   <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-validation</artifactId>
   </dependency>

2:建立自定义注解
自定义注解范围 :字段、枚举的常量、方法参数
使用@Constraint 指定校验逻辑的类

@Target({ElementType.PARAMETER,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = EnumRangeValidator.class)
public @interface CheckEnum {
	
	// 校验能输入的值
    String[] rang();
    
	// 错误提示
    String message() default "输入的内容不在规定范围";

    // 名称固定参数:校验分组信息
    Class<?>[] groups() default {};
    
    // 名称固定参数:加载的负载
    Class<? extends Payload>[] payload() default {};

}

3:建立校验逻辑的类EnumRangeValidator


public class EnumRangeValidator implements ConstraintValidator<CheckEnum,String> {

    private String[] range;

    @Override
    public void initialize(CheckEnum constraintAnnotation) {
        // 初始化将注解中的枚举内容放数组range
        range=constraintAnnotation.rang();
    }

    @Override
    public boolean isValid(String request, ConstraintValidatorContext constraintValidatorContext) {

        // 判断输入的值在不在 注解设置的范围
        if(StringUtils.isNotBlank(request)){
            if(range!=null && range.length>0){
                return Arrays.asList(range).contains(request);
            }
        }

        return false;
    }
}

4:全局异常监听控制返回
这里简单返回String 实际开发中应该定义全局返回对象

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler<T> {

    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler({MethodArgumentNotValidException.class})
    private String argumentsNotValid(MethodArgumentNotValidException e) {
        try {
            var fieldError = e.getBindingResult().getFieldError();
            var defaultMessage = fieldError.getDefaultMessage();
            log.error("参数校验不通过 ", e);
            return defaultMessage;
        } catch (NullPointerException exception) {
            log.error("fieldError 为空", e);
            return "参数异常";
        }
    }

    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(ConstraintViolationException.class)
    private String multiArgumentNotValid(ConstraintViolationException e) {
        var constraintViolations = e.getConstraintViolations();
        var reduce =
                constraintViolations.stream()
                        .map(ConstraintViolation::getMessage)
                        .reduce((x, y) -> x + " " + y)
                        .orElse("");
        log.error("参数校验不通过 ", e);
        return reduce;
    }
}

5:请求入参对象EnumValidRequest

@Data
@NoArgsConstructor
@AllArgsConstructor
public class EnumValidRequest {

    /**
     * @NotBlank 不能为空校验
     */
    @NotBlank(message = "id不能为空!")
    private String id;
    private String name;

    /**
     * 设置类型  值只能是1、2、3
     * 使用自定义枚举校验 类型只能传值1、2、3
     */
    @CheckEnum(rang = {"1","2","3"})
    private String type;
}

6:请求接口test/check/enum
使用定义的EnumValidRequest 作为参数

@Slf4j
@RestController
@RequestMapping("/test")
@Validated
public class RequestController {

    @PostMapping("/check/enum")
    public String getA(@Valid @RequestBody EnumValidRequest request){
        log.debug("a请求执行:{}",request);
        return "A";
    }

}

7:启动项目 访问接口test/check/enum

  • 输入的type不在范围时返回:
    在这里插入图片描述
  • 不传id时返回:
    在这里插入图片描述
  • 正常参数访问返回:
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值