java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > @Valid对象嵌套List对象校验无效

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

作者: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注解结合使用,以实现更全面的校验。

总结

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

您可能感兴趣的文章:
阅读全文