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

如何通过注解实现条件校验 支持单API接口适配多类型配置请求

实现方案

完全可以通过框架原生注解实现需求,无需手动编写校验逻辑,推荐使用以下最优方案:


方案1:Jackson多态反序列化 + 原生参数校验(推荐)

通过Jackson的多态注解自动根据configType将请求体反序列化为对应子类实例,配合@Valid即可自动触发子类的字段校验,全程类型安全,扩展性极强。

步骤1:定义抽象父类配置

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import jakarta.validation.constraints.NotNull;

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "configType",
        visible = true
)
@JsonSubTypes({
        @JsonSubTypes.Type(value = FileConfig.class, name = "FILE"),
        @JsonSubTypes.Type(value = LdapConfig.class, name = "LDAP")
})
public abstract class BaseConfig {
    @NotNull
    private String configType;

    //  getter、setter省略
}

步骤2:定义不同类型的子类配置,各自绑定校验规则

// 文件配置子类
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

public class FileConfig extends BaseConfig {
    @Valid
    @NotNull
    private FileSettings settings;

    public static class FileSettings {
        @NotBlank
        private String type;
        @NotBlank
        private String location;
        // getter、setter省略
    }
    // getter、setter省略
}
// LDAP配置子类
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

public class LdapConfig extends BaseConfig {
    @Valid
    @NotNull
    private LdapSettings settings;

    public static class LdapSettings {
        @NotBlank
        private String ou;
        @NotBlank
        private String attribute;
        // getter、setter省略
    }
    // getter、setter省略
}

步骤3:合并后的接口写法

@POST
@Path("/configurations")
@Consumes(MediaType.APPLICATION_JSON)
public Response createConfig(@Valid BaseConfig config) {
    // 此处config已经是反序列化完成的子类实例,直接判断类型处理逻辑即可
    if (config instanceof FileConfig fileConfig) {
        // 处理文件配置逻辑
    } else if (config instanceof LdapConfig ldapConfig) {
        // 处理LDAP配置逻辑
    }
    // 后续新增配置类型仅需新增子类+配置@JsonSubTypes即可
}

方案2:单类条件校验(不推荐)

如果不想拆分多类,可以使用Hibernate Validator提供的@ScriptAssert注解实现单类内的条件校验,缺点是无类型安全,校验规则可维护性差:

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.hibernate.validator.constraints.ScriptAssert;
import java.util.Map;

@ScriptAssert(
        lang = "javascript",
        script = "_this.configType == 'FILE' ? (_this.settings.type != null && _this.settings.location != null) : (_this.settings.ou != null && _this.settings.attribute != null)",
        message = "配置参数与configType不匹配"
)
public class UnifiedConfig {
    @NotBlank
    private String configType;
    @NotNull
    private Map<String, Object> settings;
    // getter、setter省略
}

内容的提问来源于stack exchange,提问作者Danilo Körber

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:09:03