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

Java中Jackson JSON双向引用序列化/反序列化问题求解决

Jackson双向引用反序列化UnresolvedForwardReference错误解决方法

针对双向引用导致的反序列化错误,直接用以下几种方案解决:

方案一:启用对象身份识别注解

在双向引用的两个类上都添加@JsonIdentityInfo注解,指定用对象的属性作为唯一ID,Jackson会自动处理序列化和反序列化时的引用关联:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class DemoAbstImpl {
    private Long id;
    private DemoAbstImplImpl impl;
    // Lombok @Getter/@Setter 略
}

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class DemoAbstImplImpl {
    private Long id;
    private DemoAbstImpl demoAbstImpl;
    // Lombok @Getter/@Setter 略
}

序列化时第一次出现的对象会输出完整结构,后续引用直接用ID代替;反序列化时Jackson能自动根据ID找到对应的对象,不会抛出未解析引用的错误。

方案二:用Managed/BackReference区分引用方向

如果不需要序列化反向引用的内容,直接用@JsonManagedReference和@JsonBackReference标记双向引用的两端:

public class DemoAbstImpl {
    private Long id;
    @JsonManagedReference // 标记主动引用,序列化时正常输出
    private DemoAbstImplImpl impl;
    // Lombok @Getter/@Setter 略
}

public class DemoAbstImplImpl {
    private Long id;
    @JsonBackReference // 标记反向引用,序列化时被忽略,反序列化自动关联
    private DemoAbstImpl demoAbstImpl;
    // Lombok @Getter/@Setter 略
}

这种方式简单直接,适合只需要序列化单向关联的场景,从根源避免循环引用和反序列化问题。

方案三:自定义反序列化器手动处理引用

如果前两种方案不满足业务需求,可以自定义反序列化器,手动处理未解析的正向引用:

public class DemoAbstImplImplDeserializer extends StdDeserializer<DemoAbstImplImpl> {
    public DemoAbstImplImplDeserializer() {
        super(DemoAbstImplImpl.class);
    }

    @Override
    public DemoAbstImplImpl deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode node = p.getCodec().readTree(p);
        DemoAbstImplImpl impl = new DemoAbstImplImpl();
        impl.setId(node.get("id").asLong());
        
        // 处理demoAbstImpl的未解析引用
        if (node.has("demoAbstImpl")) {
            ObjectIdReader idReader = ctxt.findObjectIdReader(DemoAbstImpl.class);
            Object refId = idReader.readObjectId(p, ctxt);
            ctxt.addUnresolvedForwardReference(impl, "demoAbstImpl", refId);
        }
        return impl;
    }
}

然后在DemoAbstImplImpl类上添加注解指定自定义反序列化器:

@JsonDeserialize(using = DemoAbstImplImplDeserializer.class)
public class DemoAbstImplImpl {
    // 类内容略
}

这种方式灵活性最高,但需要手动编写引用处理逻辑,适合复杂的业务场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 02:20:20