Spring Boot自定义注解与验证

本文介绍了Spring Boot中自定义注解@JachinLength的创建过程,包括引入依赖、定义注解、实现验证类LengthValidatorClass以及在实体类和控制器中的应用。注解原理中提到注解的生命周期(RUNTIME、CLASS、SOURCE)和可用位置,并强调@Constraint在验证属性中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注解原理与自定义注解

1、引入依赖:

<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

2、定义注解@JachinLength

利用该注解验证某字符串属性长度必须为指定长度

package com.jachin.zhujie;

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;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = LengthValidatorClass.class) // 指定验证类
public @interface JachinLength {
    int length() default 11;          // 允许字符串长度
    String message() default "kkkkk";  // 自定义的错误提示信息
  	// 下面这两个必须有
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

下面做几点说明:

1、注解的定义有点像定义接口 interface,但唯一不同的是前面需要加一个 @符号

2、注解的成员变量只能使用基本类型、 String或者 enum枚举,比如 int可以,但 Integer这种包装类型就不行。

3、像上面 @Target@Retention这种加在注解定义上面的注解,称为 “元注解”,元注解就是专门用于给注解添加注解的注解

4、 @Target(xxx) 用来说明该自定义注解可以用在什么位置,比如:

  • ElementType.FIELD说明自定义的注解可以用于类的变量
  • ElementType.METHOD说明自定义的注解可以用于类的方法
  • ElementType.TYPE说明自定义的注解可以用于类本身、接口或 enum类型

5、 @Retention(xxx) 用来说明你自定义注解的生命周期,比如:

  • @Retention(RetentionPolicy.RUNTIME):表示注解可以一直保留到运行时,因此可以通过反射获取注解信息
  • @Retention(RetentionPolicy.CLASS)表示注解被编译器编译进 class文件,但运行时会忽略
  • @Retention(RetentionPolicy.SOURCE)表示注解仅在源文件中有效,编译时就会被忽略

所以声明周期从长到短分别为:RUNTIME > CLASS > SOURCE

6、@Constraint:指定验证属性的类。

  • message()指明了验证失败后返回的消息,此方法为@Constraint要求

  • groups()和payload()也为@Constraint要求,可默认为空,详细用途可以查看@Constraint文档


3、实现验证类LengthValidatorClass

package com.jachin.zhujie;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * @description:
 * @Author: JachinDo
 * @Date: 2020/03/09 11:55
 */

public class LengthValidatorClass implements ConstraintValidator<JachinLength, String> { // 第一个参数是注解类,第二个注解是作用的对象类型
   private JachinLength length;

	// 将注解提取出来,底层利用反射生成注解的代理类
   @Override
   public void initialize(JachinLength constraint) {
      this.length = constraint;
   }
	// 验证逻辑
   @Override
   public boolean isValid(String obj, ConstraintValidatorContext context) {
      return obj.length() != length.length() ? false : true;
   }
}


4、实体类与使用controller处验证字段

实体类:

package com.jachin.zhujie;

import lombok.Data;

/**
 * @description:
 * @Author: JachinDo
 * @Date: 2020/03/09 12:06
 */
@Data
public class Person {
	// 之前定义时默认长度为11
    @JachinLength(message = "长度错误!")
    private String phone;
}

controller:

package com.jachin.zhujie;

import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

/**
 * @description:
 * @Author: JachinDo
 * @Date: 2020/03/09 13:02
 */
@RestController
@RequestMapping("/anno")

public class TestZhujie {
    @PostMapping("/phone")
    public String print(@Valid Person person,
                      BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            System.out.println("错误 " + person);
            throw new Exception(bindingResult.getFieldError().getDefaultMessage());
        }
        return person.toString();
    }
}


结果:

当输入phone长度不为11时:

在这里插入图片描述

为11时:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值