Java自定义注解对枚举类型参数的校验方法

 更新时间:2025年01月02日 12:06:56   作者:中文很快乐  
文章介绍了如何使用Java注解对枚举类型参数进行校验,通过自定义注解和注解校验类实现参数的灵活性校验,感兴趣的朋友一起看看吧

1.前提准备条件

java注解了解https://www.jb51.net/program/287468xs5.htm

1.1 pom.xml文件依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.8-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.knife4j</groupId>
    <artifactId>MyKnife4jDemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>MyKnife4jDemo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-dependencies</artifactId>
                <version>4.5.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>8.0.0.Final</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>nexus-maven</id>
            <name>nexus-maven</name>
            <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
        </repository>
    </repositories>
</project>

1.2 枚举类:

@Getter
@AllArgsConstructor
public enum RoleEnum {
    ADMIN("A", "Administrator"),
    USER("U", "User"),
    GUEST("G", "Guest");
    private final String code;
    private final String name;
    public static RoleEnum fromCode(String code) {
        for (RoleEnum role : RoleEnum.values()) {
            if (role.getCode().equals(code)) {
                return role;
            }
        }
        throw new IllegalArgumentException("Unknown code: " + code);
    }
}

1.3 controller接口:

@RequestMapping("/user")
@RestController
@Tag(name = "用户控制类")
public class UserController {
    @PostMapping("/add")
    @Operation(description = "添加数据")
    public UserDTO validCreate(@RequestBody @Valid UserDTO userDTO) {
        return userDTO;
    }
}

1.4 实体参数:

@NoArgsConstructor
@AllArgsConstructor
@Data
@Schema(description = "用户新增--DTO")
public class UserDTO {
    @Schema(description = "用户名")
    @NotBlank(message = "用户名不能为空")
    private String userName;
    @Schema(description = "用户编号")
    @NotBlank(message = "用户编号不能为空")
    private String userNo;
    @Schema(description = "角色编码")
    private String roleCode;
}

1.5 knife4j的配置

我是结合Knife4j来使用的,knife4j的详细了解使用如下链接:

knife4j的配置如下:

@Configuration
@EnableKnife4j
public class Knife4jConfig {
    @Bean
    public OpenAPI openAPI() {
        return new OpenAPI()
                .info(new Info()
                        .title("knife4j-openapi3入门测试")
                        .version("1.0")
                        .description("knife4j-openapi3项目的接口文档"));
    }
    @Bean
    public GroupedOpenApi userAPI() {
        return GroupedOpenApi.builder().group("用户信息管理").
                pathsToMatch("/user/**").
                build();
    }
}

2.实现要求

希望对参数UserDTO中的字段roleCode进行自动校验,校验roleCode参数必须且只能是枚举类中的编码的其中一个。通过注解的方式实现,最大程度上提高参数的灵活性。

3.实现步骤

3.1 自定义注解类:

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumCodeValidator.class)
public @interface ValidEnumCode {
    String message() default "must be any of enum {enumClass} codes";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    Class<? extends Enum<?>> enumClass();
}

3.2 使用注解:

在字段roleCode上添加自定义注解:

@NoArgsConstructor
@AllArgsConstructor
@Data
@Schema(description = "用户新增--DTO")
public class UserDTO {
    @Schema(description = "用户名")
    @NotBlank(message = "用户名不能为空", groups = {Create.class})
    private String userName;
    @Schema(description = "用户编号")
    @NotBlank(message = "用户编号不能为空", groups = {Update.class})
    private String userNo;
    @Schema(description = "角色编码")
    @ValidEnumCode(enumClass = RoleEnum.class,message = "Role code must be any of {codes} from {enumClass}")
    private String roleCode;
}

3.3  添加注解校验类:

public class EnumCodeValidator implements ConstraintValidator<ValidEnumCode, CharSequence> {
    private List<String> acceptedCodes;
    private String messageTemplate;
    private String enumClassName;
    @Override
    public void initialize(ValidEnumCode constraintAnnotation) {
        Class<? extends Enum<?>> enumClass = constraintAnnotation.enumClass();
        acceptedCodes = Stream.of(enumClass.getEnumConstants())
                .map(this::getEnumCode)
                .collect(Collectors.toList());
        messageTemplate = constraintAnnotation.message();
        enumClassName = enumClass.getSimpleName();
    }
    private String getEnumCode(Enum<?> enumConstant) {
        try {
            Method getCodeMethod = enumConstant.getClass().getMethod("getCode");
            return (String) getCodeMethod.invoke(enumConstant);
        } catch (Exception e) {
            throw new RuntimeException("Failed to get enum code", e);
        }
    }
    @Override
    public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }
        if (!acceptedCodes.contains(value.toString())) {
            String message = messageTemplate.replace("{enumClass}", enumClassName)
                    .replace("{codes}", String.join(", ", acceptedCodes));
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate(message)
                    .addConstraintViolation();
            return false;
        }
        return true;
    }
}

3.4 启动测试

若我传的参数如下则不通过:

后端控制台也会打印出如下提示:

若我按要求传参数,就能得到正确的结果:

4.扩展

根据我在pom中引入的参数校验依赖:hibernate-validator,

找到扩展依赖中的如下两个依赖,查看其他的可用的参数校验注解:

打开之后,根据下述提示找到可使用的注解,自己可测试使用哦

嗯,完结了,希望大家能多多对我提出点建议。

到此这篇关于Java自定义注解对枚举类型参数的校验的文章就介绍到这了,更多相关java枚举类型参数校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • jdbc连接数据库实例详解

    jdbc连接数据库实例详解

    在本篇内容里小编给大家分享了关于jdbc如何连接数据库的相关知识点内容,需要的朋友们学习下。
    2019-02-02
  • Java ArrayList中存放引用数据类型的方式

    Java ArrayList中存放引用数据类型的方式

    这篇文章主要介绍了Java ArrayList中存放引用数据类型的方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Java集合List和Map互转的方法总结

    Java集合List和Map互转的方法总结

    有时候我们需要将给定的List转换为Map,或者Map转换为List,本文主要介绍了Java集合List和Map互转的方法总结,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • Struts2的配置 struts.xml Action详解

    Struts2的配置 struts.xml Action详解

    这篇文章主要介绍了Struts2的配置 struts.xml Action详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • spring mvc 读取xml文件数据库配置参数的方法

    spring mvc 读取xml文件数据库配置参数的方法

    下面小编就为大家带来一篇spring mvc 读取xml文件数据库配置参数的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • SpringBoot整合Redis正确的实现分布式锁的示例代码

    SpringBoot整合Redis正确的实现分布式锁的示例代码

    这篇文章主要介绍了SpringBoot整合Redis正确的实现分布式锁的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • 基于SpringMVC接受JSON参数详解及常见错误总结

    基于SpringMVC接受JSON参数详解及常见错误总结

    下面小编就为大家分享一篇基于SpringMVC接受JSON参数详解及常见错误总结,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • Java Hutool 包工具类推荐 ExcelUtil详解

    Java Hutool 包工具类推荐 ExcelUtil详解

    这篇文章主要介绍了Java Hutool 包工具类推荐 ExcelUtil详解,需要引入hutool包,版本号可根据实际情况更换,除hutool包之外,还需要引入操作Excel必要包,本文给大家介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • SpringCloud中Zuul网关原理及其配置

    SpringCloud中Zuul网关原理及其配置

    Spring Cloud是一个基于Spring Boot实现的微服务应用开发工具,其中的Zuul网关可以实现负载均衡、路由转发、鉴权、限流等功能,本文将从Spring Cloud中Zuul网关的原理、使用场景和配置过程详细介绍,帮助大家更好地了解和应用Zuul网关,需要的朋友可以参考下
    2023-06-06
  • 简单介绍线性表以及如何实现双链表

    简单介绍线性表以及如何实现双链表

    本文先介绍线性表的几个基本组成部分:数组、单向链表、双向链表;随后给出双向链表的C、C++和Java三种语言的实现,需要的朋友可以参考下
    2015-07-07

最新评论