如何解决@Valid对象嵌套List对象校验无效问题

 更新时间:2024年07月11日 09:29:54   作者:Thomas & Friends  
这篇文章主要介绍了如何解决@Valid对象嵌套List对象校验无效问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

引言

在使用Spring框架进行数据校验时,有时会遇到@Valid注解无法校验嵌套的List对象的情况。

本文将介绍这个问题的原因,并提供解决方案,帮助您有效地校验嵌套的List对象。

问题背景

Spring框架提供了基于注解的数据校验功能,其中@Valid注解用于标记需要进行校验的对象。

然而,当对象中包含嵌套的List对象时,外层使用@Valid注解无法对嵌套的List对象进行校验。

原因分析

默认情况下,Spring框架对嵌套对象的校验支持较好,但对于嵌套的List对象,@Valid注解并不会自动递归进行校验。

controller如下:

public Objects flights(@RequestBody @Valid AForm aForm){
        return null;
    }

Form如下:

public class AForm {

    @NotNull(message = "数据更新时间必选")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
    private Date updateTime;

    private List<ASubForm> updateList;
}

public class ASubForm {

    @NotBlank(message = "航班号必选")
    private String FlightNumber;

    @NotBlank(message = "航班日期必选")
    private String FlightDate;

    @NotBlank(message = "离港机场必选")
    private String DepAirport;

    @NotBlank(message = "目的机场必选")
    private String ArrAirport;
}

问题

controller调用的时候只有外层的updateTime有提示数据更新时间必填,航班号航班日期等为空都不进行校验。

解决方案

修改AForm,在list对象上加上注解 @Valid就能正常校验了

public class AForm {

    @NotNull(message = "数据更新时间必选")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
    private Date updateTime;

 	@Valid
    private List<ASubForm> updateList;
}

在使用Spring框架进行数据校验时,可以在嵌套的List对象上添加@Valid注解,以启用对嵌套对象的递归校验。这样,Spring框架会自动对List中的每个元素应用校验规则。

例如:

public class YourClass {
    @Valid
    private List<YourNestedClass> nestedList;
    // 其他属性和方法
}

通过在List对象上添加@Valid注解,Spring框架会自动递归校验嵌套对象,并将校验结果返回。

这种方式是更简便的解决方案,可以避免手动递归校验或自定义注解和校验器。建议优先考虑在嵌套的List对象上使用@Valid注解来实现校验。

除了使用@Valid注解,还有其他方法可以对嵌套的List对象进行校验。以下是一些备选方案:

1.使用自定义校验器

您可以编写自定义的校验器来处理嵌套的List对象。自定义校验器可以实现对List中每个元素的校验逻辑,并进行递归校验。

首先,创建一个自定义的校验器类:

public class ListValidator implements ConstraintValidator<ValidList, List<?>> {
    @Override
    public void initialize(ValidList constraintAnnotation) {
    }

    @Override
    public boolean isValid(List<?> list, ConstraintValidatorContext context) {
        if (list == null || list.isEmpty()) {
            return true; // 空列表不进行校验
        }

        // 执行自定义的校验逻辑
        for (Object element : list) {
            // 校验每个元素
            // ...
        }

        return true; // 校验通过
    }
}

然后,创建一个自定义的注解来应用该校验器:

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ListValidator.class)
public @interface ValidList {
    String message() default "Invalid list";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

最后,在需要进行嵌套List对象校验的地方使用该注解:

public class YourClass {
    @ValidList
    private List<YourNestedClass> nestedList;
    // 其他属性和方法
}

通过自定义校验器和注解,您可以实现对嵌套的List对象的校验逻辑。

2.手动递归校验

另一种方法是手动递归校验嵌套的List对象。您可以在校验对象的方法中,手动对List对象的每个元素应用校验规则。

public class YourClass {
    private List<@Valid YourNestedClass> nestedList;
    // 其他属性和方法

    public void validate() {
        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
        Validator validator = validatorFactory.getValidator();
        for (YourNestedClass element : nestedList) {
            Set<ConstraintViolation<YourNestedClass>> violations = validator.validate(element);
            // 处理校验错误
        }
    }
}

通过手动递归校验List对象的每个元素,您可以实现对嵌套的List对象的校验。

这些是一些可选的方法,可用于对嵌套的List对象进行校验。您可以根据具体需求和情况选择适合您的解决方案。

请注意,以上方法也可以与@Valid注解结合使用,以实现更全面的校验。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java项目中多线程使用场景与实现方式详解

    java项目中多线程使用场景与实现方式详解

    在项目中,多线程的使用非常广泛,主要用于提高程序的并发性和响应速度,本文为大家整理了一些常见的多线程使用场景以及相应的实现方式,希望对大家有一定的帮助
    2025-04-04
  • Java实现二分搜索树的示例代码

    Java实现二分搜索树的示例代码

    二分搜索树是一颗二叉树,二分搜索树每个节点的左子树的值都小于该节点的值,每个节点右子树的值都大于该节点的值。本文将利用Java实现二分搜索树,需要的可以参考一下
    2022-03-03
  • 史上最简单的MyBatis动态SQL入门示例代码

    史上最简单的MyBatis动态SQL入门示例代码

    动态sql,可以根据用户对字段选择和输入,动态生成一条sql执行。接下来通过本文给大家分享MyBatis动态SQL入门示例代码,一起看看吧
    2017-03-03
  • List调用toString()方法后,去除两头的中括号实例

    List调用toString()方法后,去除两头的中括号实例

    下面小编就为大家带来一篇List调用toString()方法后,去除两头的中括号实例。希望对大家有所帮助。一起跟随小编过来看看吧
    2017-03-03
  • Maven pom.xml scope属性的使用

    Maven pom.xml scope属性的使用

    在Maven中,scope属性用于定义依赖关系在不同生命周期阶段的行为,影响依赖在构建过程中的下载和使用,以及是否传递给其他项目,常见的scope值包括compile、provided、runtime和test等
    2025-01-01
  • mybatis批量添加,批量更新之前如何判断是否已经存在

    mybatis批量添加,批量更新之前如何判断是否已经存在

    这篇文章主要介绍了mybatis批量添加,批量更新之前如何判断是否已经存在,具有很好的参考价值,希望对的有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • Java并发内存模型详情

    Java并发内存模型详情

    这篇文章主要介绍了Java并发内存模型,Java是一门支持多线程执行的语言,要编写正确的并发程序,了解Java内存模型是重要前提。而了解硬件内存模型有助于理解程序的执行,下面文章就来看看详细内容吧
    2021-10-10
  • MyBatis批量插入的五种方式小结(MyBatis以集合方式批量新增)

    MyBatis批量插入的五种方式小结(MyBatis以集合方式批量新增)

    本文主要介绍了MyBatis批量插入的五种方式小结(MyBatis以集合方式批量新增),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • 最长公共子序列问题的深度分析与Java实现方式

    最长公共子序列问题的深度分析与Java实现方式

    本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,动态规划解法通过构建DP表,显著提高了计算效率,适用于大规模数据处理
    2025-02-02
  • 详细总结各种排序算法(Java实现)

    详细总结各种排序算法(Java实现)

    下面小编就为大家带来一篇详细总结各种排序算法(Java实现)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09

最新评论