You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 07:07:49