Jackson-将json反序列化为通用类型

时间:2019-07-16 19:55:49

标签: java jackson jackson-databind

我有一个看起来像这样的模型:

@JsonIgnoreProperties(ignoreUnknown = true)
public class InputMessage<T> {

    @JsonProperty("UUID")
    private String UUID;

    @JsonProperty("MessageType")
    private String messageType;

    @JsonProperty("KeyData")
    private T keyData;

    ...

    getters/setters
}

这将在可从任意客户端调用的库中,因此KeyData字段具有通用类型。如果我尝试从客户端代码进行如下调用,则会收到ClassCastException java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class model.KeyData


编辑

尝试使用constructParametricType()的建议,但始终会出错。

ObjectMapper objectMapper = new ObjectMapper();
JavaType type = objectMapper.getTypeFactory().constructParametricType(InputMessage.class, KeyData.class);
KeyData keyData = objectMapper.readValue(inputMessage.getKeyData().toString(), type);

我要反序列化的json看起来像这样:

{
  UUID: 9bae9a6a-5553-4716-8a85-995f36df7732,
  KeyData: {
    CNSM_ID: 2,
    LGCY_SRC_ID: 123,
    PARTN_NBR: 1,
    PCD_EFF_DT: 2019-01-01,
    SRC_CD: AB
  },
  MessageType: provider_selection,
  Partition: 3,
  Rows: [
    {
      Type: l_cov_prdt_pcd_w_srch,
      SchemaID: 2,
      Value: base64encoded value
    }
  ]
}

我用来反序列化json的库是com.fasterxml.jackson.core:jackson-databind:2.9.8

任何帮助,将不胜感激。

1 个答案:

答案 0 :(得分:3)

当您将JSON反序列化为通用类时,Jackson无法猜测所使用的通用类型,因为这不是JSON中存在的信息。
并且当它不知道如何反序列化字段时,它将使用java.util.LinkedHashMap作为目标。

您想要的是通用类型,例如:

InputMessage<KeyData> inputMessage = ...;
KeyData keyData = inputMessage.getKeyData();

一种优雅的解决方法是通过指定所需的泛型为类定义Jackson JavaType
TypeFactory.constructParametricType(Class parametrized, Class... parameterClasses)允许。

假设您要反序列化为InputMessage<KeyData>,则可以执行以下操作:

JavaType type = mapper.getTypeFactory().constructParametricType(InputMessage.class, KeyData.class);
InputMessage<KeyData> keyData = mapper.readValue(json, type);

关于您的评论:

  

具有泛型类型的库代码对   KeyData类,所以我认为它属于客户端代码?

该库不需要知道此类,但是客户端应通过该类以正确执行反序列化并将通用实例返回给客户端,而不是原始类型。

例如,客户可以通过这种方式使用该库:

InputMessage<KeyData> inputMessage = myJsonLibrary.readValue("someValueIfNeeded", KeyData.class);