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

use*_*253 10 jackson

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

{
  "deliverLumpSum": 0.0,
  "faxQId": "{\"type\":\"TAKEAWAY\",\"data\":{\"orderId\":\"AWSWD-AWSAW\",\"orderKey\":\"DERS34S32SD\"}}"
}
Run Code Online (Sandbox Code Playgroud)

在以下客户解串器的帮助下

public class OrderIdDeserializer extends JsonDeserializer<OrderId> {

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

进入以下对象结构

@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;

}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `OrderId` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"type":"TAKEAWAY","data":{"orderId":"AWSWD-AWSAW","orderKey":"DERS34S32SD"}}')
Run Code Online (Sandbox Code Playgroud)

我做错了什么,我该如何解决这个问题?

谢谢

Tho*_*sch 2

首先,您的 JSON 示例 ( "faxQId":) 与您的 Java 类不匹配AddInfo

@JsonDeserialize( using = OrderIdDeserializer.class)
public OrderId orderId;
Run Code Online (Sandbox Code Playgroud)

我想这只是一个复制粘贴错误,你的意思是

@JsonDeserialize( using = OrderIdDeserializer.class)
public OrderId faxQId;
Run Code Online (Sandbox Code Playgroud)

现在来说说真正的问题。您的 JSON 内容之后"faxQId":有一个包含 JSON 代码的 JSON 字符串(带有正确转义的"引号)

"faxQId": "{\"type\":\"TAKEAWAY\",\"data\":{\"orderId\":\"AWSWD-AWSAW\",\"orderKey\":\"DERS34S32SD\"}}"
Run Code Online (Sandbox Code Playgroud)

而不是像这样的普通 JSON 对象

"faxQId": {"type":"TAKEAWAY","data":{"orderId":"AWSWD-AWSAW","orderKey":"DERS34S32SD"}}"
Run Code Online (Sandbox Code Playgroud)

因此,在反序列化器中,您需要一个额外的步骤来将此 String 反序列化为 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);
  }
}
Run Code Online (Sandbox Code Playgroud)