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规则自定义方式”的完整攻略。

阅读剩余 84%

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

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

相关文章

  • Java基础之详细总结五种常用运算符

    Java基础之详细总结五种常用运算符 Java中常见的运算符有很多种,包括算术运算符、关系运算符、逻辑运算符、位运算符等等,其中五种最为常用,本文将对这五种常用运算符进行详细总结和介绍。 算术运算符 算术运算符是Java中最基本的一类运算符,用于进行加、减、乘、除等基本的数学运算。Java中的算术运算符包括加号(+)、减号(-)、乘号(*)、除号(/)和取模…

    Java 2023年5月26日
    00
  • 利用 Linq+Jquery+Ajax 实现异步分页功能可简化带宽压力

    利用 Linq+Jquery+Ajax 实现异步分页功能可简化带宽压力的攻略包括以下几个步骤: 1. 后端接口 首先需要在后端实现一个接口用于提供分页数据,可以使用 Linq 来实现。下面是一个 C# 的示例代码: public JsonResult GetList(int pageIndex, int pageSize) { var list = db.U…

    Java 2023年5月19日
    00
  • 对象头包括哪些内容?

    以下是关于“对象头包括哪些内容?”的完整使用攻略: 1. 对象头的结构 在Java中,每个对象都有一个对象头,用于存储对象的元数据信息。对象头包含了以下几个部分: Mark Word:用于存储对象的哈希码、锁状态、GC信息等。 Class Pointer:指向对象的类元数据信息。 Array Length:仅在数组对象中存在,用于存储数组的长度。 对象头的大…

    Java 2023年5月12日
    00
  • Java日常练习题,每天进步一点点(39)

    首先,需要明确题目的大致意思:从数组中找出某个数的位置。这是一个较为基础的算法练习,主要是针对初学者对数组的使用以及查找算法的理解和掌握。 接下来,我们可以使用以下的方法来解决这个问题: 1.首先,我们需要定义一个数组,用来存储要查找的数字以及随机生成的其他数字。这里我们可以使用Java中的Random类来生成指定范围内的随机数字,代码如下: import …

    Java 2023年5月26日
    00
  • Java 数组获取最大和最小值的实例实现

    让我为您详细讲解如何实现Java数组获取最大和最小值。 1. 获取数组中的最大值 我们可以通过以下步骤获取Java数组中的最大值: 声明和初始化一个数组 使用for循环遍历数组,逐个比较数组元素大小,将最大值储存在一个变量中 输出最大值 以下是一个例子: //声明一个整型数组,包含10个元素 int[] array = {10, 8, 20, 5, 14, …

    Java 2023年5月26日
    00
  • spring boot配置拦截器代码实例

    下面我将为你详细讲解如何实现Spring Boot配置拦截器的完整攻略。 1. 准备工作 首先,你需要创建一个Spring Boot项目,可以使用Spring Initializr快速生成模板。然后,你需要在pom.xml文件中添加spring-boot-starter-web和spring-boot-starter-test依赖。 2. 创建拦截器 在Sp…

    Java 2023年5月26日
    00
  • hotspot解析jdk1.8 Unsafe类park和unpark方法使用

    Hotspot解析JDK1.8 Unsafe类park和unpark方法使用 介绍 在JDK1.8版本中,Java的Unsafe类提供了一个名为park的方法,它可以阻塞线程并等待后续被其他线程unpark唤醒。本文将详细阐述Unsafe类的park和unpark方法的原理和使用方法。 原理 Unsafe类的park方法可以使当前线程在等待队列中阻塞。当其他…

    Java 2023年5月19日
    00
  • Spring自定义参数解析器设计

    作者:京东零售 王鹏超 1.什么是参数解析器 @RequstBody、@RequstParam 这些注解是不是很熟悉? 我们在开发Controller接口时经常会用到此类参数注解,那这些注解的作用是什么?我们真的了解吗? 简单来说,这些注解就是帮我们将前端传递的参数直接解析成直接可以在代码逻辑中使用的javaBean,例如@RequstBody接收json参…

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