使用Javax Validation校验List<String>时抛出异常求助
问题:Javax Validation校验List元素时抛出HV000187异常
我尝试使用Javax Validation为List中的String元素添加@Pattern校验,简化代码如下:
DTO代码
public class ProgramRQDTO implements Serializable { private static final long serialVersionUID = -1L; @Size(min = 2, max= 5) private String lang; private List<@Pattern(regexp="^[a-zA-Z_]+$") String> destinations; // ...getters/setters }
接口代码
该DTO作为POST请求体,接口中已使用@Valid注解:
@POST @Produces({ MediaType.APPLICATION_JSON }) public Response method(@Valid @RequestBody MyDTO requestDto) { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); Set<ConstraintViolation<MyDTO>> violations = validator.validate(requestDto); // ...后续逻辑 }
调用validator.validate(requestDto)时抛出异常:
javax.validation.ValidationException: HV000187: When using type annotation constraints on parameterized iterables or map @Valid must be used. Check com.example.MyDTO#destinations
疑问:是否可以无需为List创建包装类,直接在DTO中完成校验?我是否存在操作错误?
已尝试以下几种写法,均得到相同错误:
- 在List字段上添加@Valid
@Valid private List<@Pattern(regexp="^[a-zA-Z_]+$") String> destinations; - 在类型参数上添加@Valid
private List<@Valid @Pattern(regexp="^[a-zA-Z_]+$") String> destinations; - 同时在字段和类型参数上添加@Valid
@Valid private List<@Valid @Pattern(regexp="^[a-zA-Z_]+$") String> destinations;
问题分析与解决
1. 修正类名不一致的低级错误
接口中接收的是MyDTO类型参数,但定义的DTO类是ProgramRQDTO。如果MyDTO是另一个类,其destinations字段没有正确配置校验注解,就会导致校验逻辑出错。请将接口中的参数类型修正为ProgramRQDTO:
public Response method(@Valid @RequestBody ProgramRQDTO requestDto) { // ... Set<ConstraintViolation<ProgramRQDTO>> violations = validator.validate(requestDto); // ... }
2. 确保依赖版本支持参数化类型校验
在参数化类型(如List<@Pattern String>)上添加约束是Bean Validation 2.0(JSR-380)引入的特性,对应的Hibernate Validator版本需要是6.0+。如果使用旧版本(如Hibernate Validator 5.x),这种写法不被支持,会抛出异常。
检查项目依赖,确保使用符合要求的版本:
- Maven依赖示例:
<dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.2.5.Final</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency>
3. 正确的注解写法
使用参数化类型约束时,只需在Iterable类型的字段上添加@Valid,无需在类型参数上重复添加@Valid。正确写法如下:
public class ProgramRQDTO implements Serializable { private static final long serialVersionUID = -1L; @Size(min = 2, max= 5) private String lang; @Valid private List<@Pattern(regexp="^[a-zA-Z_]+$") String> destinations; // ...getters/setters }
4. 避免重复校验
接口方法中的@Valid注解已经会触发Spring的自动校验,无需手动创建Validator实例再次校验。如需获取校验结果,可通过BindingResult参数获取:
@POST @Produces({ MediaType.APPLICATION_JSON }) public Response method(@Valid @RequestBody ProgramRQDTO requestDto, BindingResult bindingResult) { if (bindingResult.hasErrors()) { // 处理校验错误 return Response.status(Response.Status.BAD_REQUEST).build(); } // ...正常逻辑 }
内容的提问来源于stack exchange,提问作者Kain
相关产品推荐
相关产品推荐

