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

能否在自定义Java类型MyType上使用标准约束注解@Size?

解决自定义类型MyType使用@Size注解的问题

问题原因

@Size注解默认仅支持String、Collection、Map、数组等类型,自定义的MyType不在其默认支持范围内,因此hibernate-validator-annotation-processor会在编译阶段抛出类型不匹配的错误。

解决方案

要让标准@Size注解能直接应用在MyType类型字段上,需要从运行时验证支持和编译时注解处理器兼容两方面处理:

1. 实现自定义ConstraintValidator

编写一个验证器,让@Size能识别MyType类型,并提取其内部的byte[]属性进行大小校验:

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.constraints.Size;

public class MyTypeSizeValidator implements ConstraintValidator<Size, MyType> {
    private int min;
    private int max;

    @Override
    public void initialize(Size constraintAnnotation) {
        this.min = constraintAnnotation.min();
        this.max = constraintAnnotation.max();
    }

    @Override
    public boolean isValid(MyType value, ConstraintValidatorContext context) {
        // @Size默认允许null值,若需非空校验需额外添加@NotNull
        if (value == null) {
            return true;
        }
        byte[] content = value.getValue(); // 确保MyType有公开的getValue()方法获取内部byte[]
        return content.length >= min && content.length <= max;
    }
}

2. 注册验证器

方式A:SPI自动注册(推荐)

在项目的src/main/resources/META-INF/services目录下创建文件jakarta.validation.ConstraintValidator,写入你的验证器全类名:

com.yourpackage.MyTypeSizeValidator

Hibernate Validator会通过服务加载机制自动识别并启用该验证器。

方式B:Spring环境程序式注册

如果是Spring项目,也可以通过配置类手动注册:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

@Configuration
public class ValidatorConfig {
    @Bean
    public LocalValidatorFactoryBean validator() {
        LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
        factoryBean.getConstraintValidatorFactory().addConstraintValidator(Size.class, MyType.class, new MyTypeSizeValidator());
        return factoryBean;
    }
}

3. 解决编译时注解处理器报错

创建约束映射文件,告诉hibernate-validator-annotation-processor:@Size支持MyType类型。在src/main/resources/META-INF/validation/constraint-mappings.xml中添加以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<constraint-mappings xmlns="https://jakarta.ee/xml/ns/jakartaee"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/validation-mapping-3.0.xsd"
                     version="3.0">
    <constraint-definition annotation="jakarta.validation.constraints.Size">
        <validated-by>
            <value>com.yourpackage.MyTypeSizeValidator</value>
        </validated-by>
        <target>
            <value>com.yourpackage.MyType</value>
        </target>
    </constraint-definition>
</constraint-mappings>

备选方案:嵌套验证(不推荐,不符合需求)

如果不想扩展@Size的支持范围,也可以在MyType内部的byte[]字段上直接添加@Size,然后在DTO的MyType字段上添加@Valid触发嵌套验证:

public class MyType {
    @Size(max = 100)
    private byte[] value;

    // getter、setter方法
}

public class SampleDTO {
    @Valid
    public MyType fileContent;
}

但此方案需要修改MyType的内部实现,无法让使用者直接在MyType字段上使用@Size,仅作为备选。

内容的提问来源于stack exchange,提问作者bobbyrne01

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:03:18