如何解决@Valid对象嵌套List对象校验无效问题
作者:Thomas & Friends
引言
在使用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注解结合使用,以实现更全面的校验。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。