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

解决Jackson中属性的Getter定义冲突问题

解决Jackson Getter冲突与多类型JSON字段映射问题

问题场景

你编写的Java类如下:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Getter;
import lombok.Setter;

import java.util.List;

@Getter
@Setter
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class Options {
    @JsonProperty("value")
    private String value;
    @JsonProperty("value")
    private Value valueObj;
}

使用Jackson处理JSON时出现错误:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Conflicting getter definitions for property "value": Options#getValue() vs Options#getValueObj()

需要复用Options类映射的JSON数据如下:

{
    "behaviors": [
        {
            "name": "dnsAsyncRefresh",
            "options": {
                "enabled": true,
                "timeout": "1h",
                "value": {
                    "id": "1234"
                }
            }
        },
        {
            "name": "timeout",
            "options": {
                "value": "5s"
            }
        }
    ]
}

错误原因

你给两个不同字段都标记了@JsonProperty("value"),Lombok自动生成的getValue()和getValueObj()方法会被Jackson同时识别为JSON字段value的getter,导致属性映射冲突。

解决方案

方案1:用Object类型统一接收多类型value

将两个value相关字段合并为一个Object类型的字段,Jackson会自动根据JSON中的实际类型(字符串或对象)填充该字段,同时避免getter冲突。

修改后的Options类:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class Options {
    private Boolean enabled;
    private String timeout;
    @JsonProperty("value")
    private Object value;

    // 辅助方法:快速获取String类型的value
    public String getValueAsString() {
        return (value instanceof String) ? (String) value : null;
    }

    // 辅助方法:快速获取Value对象类型的value
    public Value getValueAsValueObj() {
        return (value instanceof Value) ? (Value) value : null;
    }
}

对应的Value类:

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Value {
    private String id;
}

方案2:自定义反序列化器(类型更严谨)

如果需要对类型转换做更严格的控制,可以自定义反序列化器,根据JSON节点的类型决定反序列化为String还是Value对象。

第一步:编写自定义反序列化器

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;

import java.io.IOException;

public class ValueDeserializer extends JsonDeserializer<Object> {
    @Override
    public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode node = p.getCodec().readTree(p);
        if (node.isTextual()) {
            return node.asText();
        } else if (node.isObject()) {
            return p.getCodec().treeToValue(node, Value.class);
        }
        return null;
    }
}

第二步:在Options类中应用该反序列化器

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class Options {
    private Boolean enabled;
    private String timeout;
    @JsonProperty("value")
    @JsonDeserialize(using = ValueDeserializer.class)
    private Object value;

    // 同样可以添加辅助方法便捷取值
    public String getValueAsString() {
        return (value instanceof String) ? (String) value : null;
    }

    public Value getValueAsValueObj() {
        return (value instanceof Value) ? (Value) value : null;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 04:00:02