为了账号安全,请及时绑定邮箱和手机立即绑定

杰克逊:尝试将 JSON 反序列化为 Java 对象时未解析的前向引用

杰克逊:尝试将 JSON 反序列化为 Java 对象时未解析的前向引用

隔江千里 2022-09-22 16:27:13

我已经陷入了一个问题很长一段时间了,我渴望解决它。我有一个对象,其中包含带有ID相互引用的对象,我需要将其反序列化为对象,但是在尝试这样做时,我不断得到。JacksonJSONUnresolved forward references exception


我尝试过使用上面的注释类,但这没有产生任何结果。Jackson@JsonIdentityInfo


JSON 示例:


{

  "customer": [

    {

      "id": 1,

      "name": "Jane Gallow",

      "age": 16

    },

    {

      "id": 2,

      "name": "John Sharp",

      "age": 20

    },

  ],

  "shoppingcart": [

    {

      "id": 1,

      "customer": 2,

      "orderDate": "2015-02-19"

    }

  ]

}

客户类



@JsonIdentityInfo(generator= ObjectIdGenerators.PropertyGenerator.class, property="id",scope = Customer.class)

@JsonIdentityReference(alwaysAsId = true)

public class Customer {


    private int id = -1;


    private String name;


    private int age;


    //getters, setters

}

购物车类



<!-- language: java -->


@JsonIdentityInfo(generator= ObjectIdGenerators.PropertyGenerator.class, property="id",scope = ShoppingCart.class)

public class ShoppingCart {


    private int id = -1;


    private Customer customer;


    @JsonDeserialize(using = LocalDateDeserializer.class)

    @JsonSerialize(using = LocalDateSerializer.class)

    private LocalDate orderDate = LocalDate.now();


    //getters, setters

}

我希望给我一个对象,该对象具有对id中的对象的引用(在本例中为约翰·夏普)。但是我只是无法让它工作,当我尝试使用方法从JSON读取时,它会给我。JacksonShoppinCartCustomer2"main" com.fasterxml.jackson.databind.deser.UnresolvedForwardReferenceObjectMapper.readValue()


查看完整描述

2 回答

?
波斯汪

TA贡献1478条经验 获得超4个赞

您应该对属性使用 JsonIdentity 引用

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = ShoppingCart.class)

class ShoppingCart {


    private int id = -1;


    @JsonIdentityReference

    private Customer customer;

    private LocalDate orderDate;


    // getters, setters, toString

}


@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Customer.class)

class Customer {


    private int id = -1;

    private String name;

    private int age;


    // getters, setters, toString

}

简单示例:


import com.fasterxml.jackson.annotation.JsonIdentityInfo;

import com.fasterxml.jackson.annotation.JsonIdentityReference;

import com.fasterxml.jackson.annotation.JsonProperty;

import com.fasterxml.jackson.annotation.ObjectIdGenerators;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.databind.SerializationFeature;

import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;


import java.io.File;

import java.time.LocalDate;

import java.util.List;


public class JsonApp {


    public static void main(String[] args) throws Exception {

        File jsonFile = new File("./resource/test.json").getAbsoluteFile();


        ObjectMapper mapper = new ObjectMapper();

        mapper.registerModule(new JavaTimeModule());

        mapper.enable(SerializationFeature.INDENT_OUTPUT);


        System.out.println(mapper.readValue(jsonFile, Pojo.class));

    }

}

对于您的打印件:JSON


Pojo{customers=[Customer{id=1, name='Jane Gallow', age=16}, Customer{id=2, name='John Sharp', age=20}], shoppingCarts=[ShoppingCart{id=1, customer=Customer{id=2, name='John Sharp', age=20}, orderDate=2015-02-19}]}


查看完整回答
反对 回复 4天前
?
慕田峪4524236

TA贡献1546条经验 获得超5个赞

在反序列化过程中,我对未解析的正向引用也有同样的问题。我使用 https://www.logicbig.com/tutorials/misc/jackson/json-identity-reference.html 上提供的示例来检查并解决我的问题。有一个非常简单的类:


public class Order {

  private int orderId;

  private List<Integer> itemIds;

  private Customer customer;

....

}

我向 Customer 类添加了@JsonCreator静态工厂方法,它没有导致任何问题。


现在,当我将任何类型的@JsonCreator(静态方法或构造函数)添加到 Order 类时,我会立即获得未解析的前向引用。有趣的是,当我添加以下构造函数时,只有@JsonPropery个注释:


 public Order(@JsonProperty("orderId") int orderId, @JsonProperty("itemIds") List<Integer> itemIds, @JsonProperty("customer") Customer customer) {

    this.orderId = orderId;

    this.itemIds = itemIds;

    this.customer = customer;

}

它还会导致未解析的前向引用。


要解决此问题,对于 Order 类,您必须创建无参数构造函数(可以是私有的)。否则,您将获得:


线程“主”中的异常:无法构造实例(没有创建者,如默认构造存在):无法从对象值反序列化(没有基于委托或基于属性的创建者)com.logicbig.example.Order


并且不得有任何@JsonCreator带注释的方法和构造函数,或者具有@JsonProperty批注的构造函数。


仅此而已。


查看完整回答
反对 回复 4天前

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信