SpringBoot之groups应对不同的Validation规则自定义方式

下面是详细讲解“SpringBoot之groups应对不同的Validation规则自定义方式”的完整攻略。

什么是Validation

Validation是指对象验证,是一种可以验证Java对象的一组功能。在Java中,我们通常使用JSR 303规范中提供的Validation API来完成对象验证。

什么是Validation groups

Validation groups是Validation API中的一种概念。它允许我们将验证规则分组,从而能够让我们针对不同的场景使用不同的验证规则。

如何自定义Validation rules with group

在Spring Boot中使用Validation API,我们可以通过自定义Validation rules with group来实现利用groups应对不同的Validation规则。

具体实现步骤如下:

  1. 定义Validation Group
    我们需要定义出多个Validation Group。例如,我们可以定义出CreateGroup、UpdateGroup、DeleteGroup等Group,分别对应创建、更新、删除API的输入参数。定义方式如下:

```java
public interface CreateGroup { }

public interface UpdateGroup { }

public interface DeleteGroup { }
```

  1. 在需要进行参数验证的接口输入参数上使用@Validated注解,同时指定要进行验证的Group。例如:

java
public ResultDTO<?> create(@Validated(CreateGroup.class) @RequestBody CreateUserDTO createUserDTO) { }

  1. 在输入参数类上使用注解@GroupSequence,定义Group的顺序。例如:

```java
public class CreateUserDTO {

   @NotNull(groups = {CreateGroup.class})
   private String name;

   @Min(value = 18, groups = {CreateGroup.class})
   private Integer age;

   @NotNull(groups = {UpdateGroup.class})
   private Long id;

   @GroupSequence({CreateGroup.class, UpdateGroup.class})
   public interface Group { }

}
```

这样,在执行参数验证时,会按照指定的Group顺序逐个验证。

  1. 在需要对某个Group使用自定义验证规则时,我们需要自定义验证类,并且让它实现javax.validation.ConstraintValidator接口。例如,我们需要对CreateGroup进行自定义验证,规则为:对象长度不能小于3。实现如下:

```java
public class CreateGroupValidator implements ConstraintValidator {

   @Override
   public boolean isValid(Object value, ConstraintValidatorContext context) {
       if (value == null) {
           return true;
       }
       return value.toString().length() >= 3;
   }

}
```

  1. 在需要使用自定义验证规则的属性上使用自定义注解,例如,我们需要对name属性使用自定义验证规则,实现如下:

java
@NotNull(groups = {CreateGroup.class})
@CreateGroupValidator(groups = {CreateGroup.class}, message = "长度不能小于3")
private String name;

这样,我们就成功地利用groups应对不同的Validation规则,并且实现了自定义的验证规则。下面,我来举两个简单的例子。

例子一:对输入参数进行校验

我们有一个用户管理系统,其中有一个创建用户的接口。输入参数为一个JSON格式的DTO对象,其中包含用户名和年龄两个字段。我们希望在创建用户时,能够对输入参数进行验证,避免出现不合法数据。

首先,我们引入Validation API依赖,定义出CreateGroup:

public interface CreateGroup { }

我们在输入参数类上使用注解@GroupSequence,定义Group的顺序,同时标注出要验证的属性及其规则:

@Data
@NoArgsConstructor
public class CreateUserDTO {

    @NotNull(groups = {CreateGroup.class})
    @Length(min = 1, max = 20, groups = {CreateGroup.class}, message = "长度必须为1-20个字符")
    private String name;

    @NotNull(groups = {CreateGroup.class})
    @Min(value = 0, groups = {CreateGroup.class}, message = "年龄必须大于等于0")
    @Max(value = 150, groups = {CreateGroup.class}, message = "年龄不能大于150")
    private Integer age;

    @GroupSequence({CreateGroup.class})
    public interface Group { }
}

我们在控制器上加上注解@Validated,并指定创建时需要验证CreateGroup。同时,在控制器方法中在输入参数上标注@RequestBody注解:

@RestController
@RequestMapping(value = "/users")
@Validated
public class UserController {

    @PostMapping
    public ResultDTO<?> create(@Validated(CreateUserDTO.Group.class) @RequestBody CreateUserDTO createUserDTO) {
        // 写业务代码
        return new ResultDTO<>();
    }
}

现在,我们来测试一下这个接口,看看它对于不合法的输入参数是否能够真正地进行校验:

  1. 测试数据:

json
{
"name": "",
"age": -1
}

  1. 发送请求,预期结果:

{
"code": "InvalidArgument",
"message": "参数错误",
"data": {
"name": [
"长度必须为1-20个字符"
],
"age": [
"年龄必须大于等于0"
]
}
}

  1. 测试数据:

json
{
"name": "test",
"age": 1500
}

  1. 发送请求,预期结果:

{
"code": "InvalidArgument",
"message": "参数错误",
"data": {
"age": [
"年龄不能大于150"
]
}
}

我们可以发现,因为设置了Validation Group,这个接口能够很好地对输入参数进行校验。

例子二:对属性进行自定义校验

我们有一个管理学校课程的系统,它包括若干个课程信息。课程信息包含了课程名称和老师名称两个字段。我们希望在创建新课程信息时,对课程名称和老师名称进行校验。其中,对于课程名称,我们希望其长度不能小于3;对于老师名称,我们希望其以"Teacher_"开头。

首先,我们引入Validation API依赖,并定义自定义Annotation:

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = TeacherNameValidator.class)
public @interface TeacherName {

    String message() default "老师名称必须以 \"Teacher_\" 开头";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}

我们实现ConstraintValidator接口:

public class TeacherNameValidator implements ConstraintValidator<TeacherName, String> {

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) {
            return false;
        }
        return value.startsWith("Teacher_");
    }
}

我们在输入参数类上定义Group,并使用@TeacherName注解标注老师名称属性:

@Data
@NoArgsConstructor
public class CourseDTO {

    @NotNull(groups = {CreateGroup.class})
    @Length(min = 3, max = 20, groups = {CreateGroup.class}, message = "长度必须在3-20个字符之间")
    private String name;

    @TeacherName(groups = {CreateGroup.class}, message = "老师名称必须以 \"Teacher_\" 开头")
    private String teacher;

    @GroupSequence({CreateGroup.class})
    public interface Group { }
}

在控制器上加上注解@Validated,并指定创建时需要验证CreateGroup。同时,在控制器方法中在输入参数上标注@RequestBody注解:

@RestController
@RequestMapping(value = "/courses")
@Validated
public class CourseController {

    @PostMapping
    public ResultDTO<?> create(@Validated(CourseDTO.Group.class) @RequestBody CourseDTO courseDTO) {
        // 写业务代码
        return new ResultDTO<>();
    }
}

现在,我们来测试一下这个接口,看看它对于不合法的输入参数是否能够真正地进行校验:

  1. 测试数据:

json
{
"name": "A",
"teacher": "B"
}

  1. 发送请求,预期结果:

{
"code": "InvalidArgument",
"message": "参数错误",
"data": {
"name": [
"长度必须在3-20个字符之间"
],
"teacher": [
"老师名称必须以 \"Teacher_\" 开头"
]
}
}

  1. 测试数据:

json
{
"name": "Java",
"teacher": "Teacher_Li"
}

  1. 发送请求,预期结果:

{
"code": "OK",
"message": "创建成功",
"data": null
}

在这个例子中,我们对多个属性进行了不同的Validation规则的自定义,而且它们都成功地被执行了。

至此,我们就完成了“SpringBoot之groups应对不同的Validation规则自定义方式”的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot之groups应对不同的Validation规则自定义方式 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • JavaScript反射与依赖注入实例详解

    JavaScript 反射与依赖注入实例详解 JavaScript 反射和依赖注入是现代 web 应用程序发展中的两个重要的技术,本文将深入讨论这两个概念,并提供一些具体的实例和攻略。 什么是 JavaScript 反射? JavaScript 反射是一种技术,它可以在运行时检查一个对象的属性和方法,并对其进行操作。这通常用于创建更动态和灵活的应用程序。 如…

    Java 2023年5月26日
    00
  • spring容器启动实现初始化某个方法(init)

    在Spring容器启动时,我们可以通过在Bean上添加@PostConstruct注解或实现InitializingBean接口来实现初始化某个方法。在本文中,我们将详细讲解如何在Spring容器启动时实现初始化某个方法。 使用@PostConstruct注解 @PostConstruct注解是javax.annotation包中的注解,它可以用来标记一个方…

    Java 2023年5月18日
    00
  • 基于Java开发实现ATM系统

    基于Java开发实现ATM系统的完整攻略 ATM系统是一个常见的银行自动化服务系统,能够提供客户便捷的取款、转账、查询等服务。本文将介绍如何使用Java开发一个简单的ATM系统,主要包含以下步骤: 1. 需求分析 在开始开发之前,需要明确该系统的具体需求,包括系统的功能和用户交互方式等。对于ATM系统,我们可以初步确定以下需求: 用户需要能够登录系统,通过录…

    Java 2023年5月19日
    00
  • Java实现简单的酒店管理系统

    Java实现简单的酒店管理系统 系统需求 在开始编写系统代码之前,需要明确系统需求,以确定需要实现哪些功能。 管理员登录:管理员通过用户名和密码登录酒店管理系统。 房间管理:管理员可以添加、修改和删除房间信息,包括房间类型、房间号、房间价格、房间状态等。 客户管理:管理员可以添加、修改和删除客户信息,包括客户姓名、客户身份证号、客户联系方式等。 预定管理:管…

    Java 2023年5月19日
    00
  • JAVA annotation入门基础

    JAVA annotation入门基础 什么是Annotation? Annotation 是Java5.0引入的注解机制,它提供了一种注释程序的方法,这些注释可以在编译期,类加载期或者运行期被读取和处理。Annotation 可以看作是程序中的元数据,它提供数据给程序员,让程序员在编写程序时能够更加充分地利用Java语言的特性。Annotation 是Ja…

    Java 2023年5月26日
    00
  • spring mvc 和ajax异步交互完整实例代码

    Spring MVC和Ajax异步交互完整实例代码 Spring MVC是一种基于Java的Web框架,它可以帮助我们快速开发Web应用程序。在Web应用程序中,Ajax异步交互是一种常见的技术,它可以帮助我们实现无需刷新页面的数据交互。本文将详细讲解Spring MVC和Ajax异步交互的完整实例代码,并提供两个示例说明。 步骤一:创建Controller…

    Java 2023年5月18日
    00
  • 搞懂Java线程池

    搞懂Java线程池 简介 Java中的线程池是一种常见的并发编程工具,它可以让程序更高效地利用系统资源以及更好地进行线程管理。线程池采用预分配线程的方式,从而避免了线程的频繁创建与销毁,这样可以在一定程度上提升程序的性能。同时,线程池还可以对线程进行池化、回收、重用等操作,从而进一步提升程序的运行效率。 线程池的使用 Java线程池的使用十分简洁,可以分为几…

    Java 2023年5月18日
    00
  • Java矩阵连乘问题(动态规划)算法实例分析

    下面是详细讲解“Java矩阵连乘问题(动态规划)算法实例分析”的完整攻略。 标题 Java矩阵连乘问题(动态规划)算法实例分析 总述 在计算机科学中,矩阵乘法是一个常见的计算问题。 当需要计算大型矩阵的乘积时,可以使用分治法,但这不是一个好的选择,因为分治法带来的额外开销很多。 在这种情况下,动态规划是解决矩阵连乘问题的最好选择。 步骤 下面是Java实现矩…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部