共计 1028 个字符,预计需要花费 3 分钟才能阅读完成。
问题论述:
以后对于 controller 层的 request 的参数校验,常常会应用到 javax.validation 包下的 @Valid 注解,在对应的 javabean 中应用各种 javax.validation.constraints 下的各种注解实现校验。
然而当传输参数为 list 或者其余非 object 的 collection 时,会发现校验并不失效。
起因是这种形式是通过
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor 调用的 org.hibernate.validator.internal.engine.ValidatorImpl 中的 validate 办法进行校验,但仅仅只会校验 object 的各个属性,并不会校验 list 中的各个 elements。
解决方案:配合 @Validated 应用 @Valid
将 @Validated 搁置在 controller 类上,同时持续应用 @Valid 和 @requestBody 在申请参数前,此时这种形式会通过
org.springframework.validation.beanvalidation.MethodValidationInterceptor 调用 org.hibernate.validator.internal.engine.ValidatorImpl 中的 validateParameters 办法,该办法会校验 list 中的各个 element。
区别:
传统的第一种形式会间接抛出 400。第二种形式是经由 controller 类抛出 ConstraintViolationException,第二种形式是更加普适的能够用于所有的类中办法的参数校验,并不专用于 controller 层,如果想取得相似第一种形式的 exception,须要在 @RestControllerAdvice 的 globalhandler 做一下异样解决。
其余计划:
1⃣️能够尝试将传输的参数变为 object,继而将 list 作为 object 的一个 field,然而这种形式会要求调用方做相应的改变。
2⃣️将 list 变为一个 javabean,实现相似如下:
@Data
public class ValidList<E> implements List<E> {
@Valid
@Delegate
private List<E> list = new ArrayList<>();
}