Jackson反序列化错误:没有字符串参数构造函数/工厂方法可用于从字符串值反序列化

12

我正在尝试反序列化以下JSON

{
  "deliverLumpSum": 0.0,
  "faxQId": "{\"type\":\"TAKEAWAY\",\"data\":{\"orderId\":\"AWSWD-AWSAW\",\"orderKey\":\"DERS34S32SD\"}}"
}

通过以下自定义反序列化程序的帮助

public class OrderIdDeserializer extends JsonDeserializer<OrderId> {

  @Override
  public OrderId deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
      OrderId orderId = jsonParser.readValueAs(OrderId.class);
      return orderId;
  }
}

转换为下面的对象结构

@Data
public class AddInfo {

  protected double deliverLumpSum;
  
  @JsonDeserialize( using = OrderIdDeserializer.class)
  public OrderId orderId;

}

@Data
public class OrderId {

  private String type;
  private TakeawayData data;

}

@Data
public class TakeawayData {

  private String orderId;
  private String orderKey;

}

我遇到了以下错误
com.fasterxml.jackson.databind.exc.MismatchedInputException: 无法构造OrderId的实例(尽管至少存在一个创建者):没有字符串参数构造函数/工厂方法可以反序列化从字符串值('{"type" :"TAKEAWAY","data":{"orderId":"AWSWD-AWSAW","orderKey":"DERS34S32SD"}}')
我做错了什么,如何解决这个问题?

5
你最终解决了这个问题吗? - fanfavorite
1个回答

2
首先,你的JSON示例(“faxQId”)与Java类AddInfo不匹配。
@JsonDeserialize( using = OrderIdDeserializer.class)
public OrderId orderId;

我猜这只是一个复制粘贴的错误,你真正想说的是什么。
@JsonDeserialize( using = OrderIdDeserializer.class)
public OrderId faxQId;

现在来谈谈真正的问题。在"faxQId":之后,您的JSON内容包含一个JSON字符串,其中包含JSON代码(带有正确转义的"引号)。
"faxQId": "{\"type\":\"TAKEAWAY\",\"data\":{\"orderId\":\"AWSWD-AWSAW\",\"orderKey\":\"DERS34S32SD\"}}"

不再是普通的 JSON 对象,而是更加丰富多彩的形式。

"faxQId": {"type":"TAKEAWAY","data":{"orderId":"AWSWD-AWSAW","orderKey":"DERS34S32SD"}}"

因此,在您的反序列化程序中,您需要额外增加一步操作来将该字符串反序列化为Java对象。
public class OrderIdDeserializer extends JsonDeserializer<OrderId> {

  @Override
  public OrderId deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {

    // Get the JSON text (with the \ already decoded):
    // {"type":"TAKEAWAY","data":{"orderId":"AWSWD-AWSAW","orderKey":"DERS34S32SD"}}
    String s = jsonParser.getValueAsString();
      
    // We need a second parser for deserializing the JSON text
    JsonParser jsonParser2 = jsonParser.getCodec().getFactory().createParser(s);

    // Convert the JSON text into an object
    return jsonParser2.readValueAs(OrderId.class);
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接