【问题标题】:Mapping Json Array to POJO using Jackson使用 Jackson 将 Json 数组映射到 POJO
【发布时间】:2019-08-10 22:09:20
【问题描述】:

我有一个 JSON 数组,格式如下:

[
 [
  1232324343,
  "A",
  "B",
  3333,
  "E"
 ],
 [
  12345424343,
  "N",
  "M",
  3133,
  "R"
 ]
]

我想使用 Jackson 库将父数组的每个元素映射到 POJO。我试过这个:

ABC abc = new ABC();
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(data).get("results");

if (jsonNode.isArray()) {
    for (JsonNode node : jsonNode) {
        String nodeContent = mapper.writeValueAsString(node);
        abc = mapper.readValue(nodeContent,ABC.class);

        System.out.println("Data: " + abc.getA());
    }
}

ABC 是我的 POJO 类,abc 是对象,但出现以下异常:

com.fasterxml.jackson.databind.JsonMappingException: 无法反序列化 com.demo.json.model.ABC 的实例

编辑: 我的 POJO 是这样的:

class ABC{
    long time;
    String a;
    String b;
    int status;
    String c;
}

有人可以为此提出解决方案吗?

编辑 2:在 StackOverflow 和其他论坛上咨询了很多答案后,我遇到了一个解决方案。我将 readValue() 方法的返回值映射到 POJO 对象数组中。

ABC[] abc = mapper.readValue(nodeContent, ABC[].class);

但现在我得到了一个单独的异常

无法构造 ABC 的实例:没有 long/Long-argument 构造函数/工厂方法来反序列化 Number 值 (1552572583232)

我尝试了以下方法,但没有任何效果: 1. 强制 Jackson 使用 int 作为长值使用

mapper.configure(DeserializationFeature.USE_LONG_FOR_INTS, true);

2。在 POJO 中使用包装类 Long 而不是 long

谁能帮我解决这个问题?

【问题讨论】:

  • 取决于你的 POJO 是什么样子的。
  • @RobbyCornelissen 我已将 POJO 结构添加为编辑。请看一下
  • 我猜你需要CustomDeserializer
  • 很好的问题,从 25 分钟开始。
  • 在您的情况下,node 是什么?为什么要基于它生成JSON,然后反序列化为ABC 类?

标签: java json jackson-databind


【解决方案1】:

您可以为此对象使用ARRAY 形状。您可以使用JsonFormat 注释来做到这一点:

@JsonFormat(shape = Shape.ARRAY)
class ABC {

然后反序列化它:

ABC[] abcs = mapper.readValue(json, ABC[].class);

在有问题的更改后进行编辑。

您的示例代码可能如下所示:

JsonNode jsonNode = mapper.readTree(json);
if (jsonNode.isArray()) {
    for (JsonNode node : jsonNode) {
        String nodeContent = mapper.writeValueAsString(node);
        ABC abc = mapper.readValue(nodeContent, ABC.class);

        System.out.println("Data: " + abc.getA());
    }
}

我们可以使用convertValue方法跳过序列化过程:

JsonNode jsonNode = mapper.readTree(json);
if (jsonNode.isArray()) {
    for (JsonNode node : jsonNode) {
        ABC abc = mapper.convertValue(node, ABC.class);
        System.out.println("Data: " + abc.getA());
    }
}

甚至:

JsonNode jsonNode = mapper.readTree(json);
ABC[] abc = mapper.convertValue(jsonNode, ABC[].class);
System.out.println(Arrays.toString(abc));

【讨论】:

  • 看起来很酷。我不知道仅使用注释就可以实现。
  • 不幸的是我无法让它工作。我也没有高兴地尝试过@JsonPropertyOrder({"time", "a", "b", "status", "c"})。
  • 刚刚将 Lombok 的 @Data 添加到 ABC 类中(相当于添加了 getter、setter、默认构造函数、equals() 和 hashCode() 方法),它没有任何问题。
  • @cassiomolin,您需要有明确的 POJO 类才能使其工作。
  • 我必须根据我在 JSON 数组中接收到的数据对 POJO 中的数据成员进行排序。结合@JsonFormat 注解,这让我的代码工作了
【解决方案2】:

您的 json 未映射到您定义的 pojo。对于您定义的 pojo,json 应为以下格式。

{ 
  "time:1232324343,
  "a":"A",
  "b":"B",
  "status":3333,
  "c":"E"
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多