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

API二次调用报JSON反序列化错误:zipCode属性Setter冲突

问题分析

错误核心是Jackson反序列化MetaAddress中的Address对象时,发现zipCode属性存在两个冲突的setter方法:setZipCode(String)和setZipCode(String[])。即便给其中一个添加@JsonIgnore也无效,原因是Lombok的@Data注解会自动生成getter/setter,你手动编写的setter与自动生成的(或自身定义的另一个)形成重复定义;且单独使用Address类时,Jackson的处理逻辑与嵌套在MetaAddress中不同,导致冲突仅在嵌套场景暴露。

解决方案

方案1:合并setter逻辑,兼容两种输入格式

只保留一个setter方法,通过判断输入类型同时处理字符串和数组格式的zipCode,彻底避免方法冲突:

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public final class Address implements Serializable {

    private String id;
    private String zipCode;
    private String city;

    @JsonSetter
    public void setZipCode(Object zipCode) {
        if (zipCode instanceof String[]) {
            this.zipCode = ((String[]) zipCode)[0];
        } else if (zipCode instanceof String) {
            this.zipCode = (String) zipCode;
        }
        // 可按需补充null或其他类型的处理逻辑
    }
}

方案2:禁用Lombok自动生成zipCode的setter,手动控制方法签名

通过@Setter(AccessLevel.NONE)阻止Lombok生成zipCode的setter,同时给数组版本的setter重命名,避免方法签名冲突:

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
// 禁止Lombok自动生成zipCode的setter
@Setter(AccessLevel.NONE)
public final class Address implements Serializable {

    private String id;
    private String zipCode;
    private String city;

    // 字符串版本setter标记为Jackson忽略,仅用于业务代码调用
    @JsonIgnore
    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }

    // 数组版本setter指定对应json字段,方法名避免重复
    @JsonSetter("zipCode")
    public void setZipCodeFromStringArray(String[] zipCode) {
        this.zipCode = zipCode[0];
    }
}

方案3:自定义Jackson反序列化器

通过自定义反序列化器完全控制zipCode的解析逻辑,无需编写多个setter:

  1. 编写反序列化器类:
public class ZipCodeDeserializer extends JsonDeserializer<String> {
    @Override
    public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode node = p.getCodec().readTree(p);
        if (node.isArray()) {
            return node.get(0).asText();
        } else if (node.isTextual()) {
            return node.asText();
        }
        return null;
    }
}
  1. 在Address类的zipCode字段上应用注解:
@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public final class Address implements Serializable {

    private String id;
    @JsonDeserialize(using = ZipCodeDeserializer.class)
    private String zipCode;
    private String city;
}
场景差异说明

单独使用Address类时,Jackson可能在首次序列化/反序列化时缓存了简化的类处理规则;而嵌套在MetaAddress中时,类的初始化或缓存逻辑触发了完整的方法校验,导致冲突被检测到。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 18:37:14