当前位置: 首页 > 知识库问答 >
问题:

如何反序列化嵌套JSON数组到地图使用Java的杰克逊库?

上官和惬
2023-03-14

我有一个这样的结构:

{
    "name": "user",
    "values":[["0.00207760","18.48000000"],["0.00207740","40.00000000"],["0.00207710","2.26000000"]]
}

我想使用流行的Jackson库反序列化为这样的类:

public class Values {

    public String name;

    public Map<BigDecimal, BigDecimal> values = new HashMap<>();

}

其中,values属性中的每个条目都成为类映射中的键/值条目。

然而,如果我尝试用Jackson进行简单的反序列化,我会得到以下错误:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.TreeMap<java.lang.Object,java.lang.Object>` out of START_ARRAY token
 at [Source: (String)"{"name": "user","values":[["0.00207760","18.48000000"],["0.00207740","40.00000000"],["0.00207710","2.26000000"]]...
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1442)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1216)
    ...

使用Jackson如何实现这一点?

谢谢

爱德华多

共有2个答案

周志文
2023-03-14

列表

https://riptutorial.com/java/example/18575/deserialize-json-collection-to-collection-of-objects-using-jackson给了我答案。

JSON格式:

{
 "history": [
  [
    2,
    {
      "trx_id": "4014ae64ae9c45861ed4f0af30224b6741dcbb46",
      ...
      "operation_id": 0
    }
  ],
  [
    3,
    {
      "trx_id": "a4023a3641ffc112324427523945f641d88c5eae",
      ...
      "operation_id": 0
    }
  ]
 ]
}

3类回答:

public class HistoryListResponse {
   private List<HistoryMapEntryResponse> history;
}

2人班:

@JsonFormat(shape = JsonFormat.Shape.ARRAY)
@JsonPropertyOrder({ "key", "trx"})
public class HistoryMapEntryResponse {
  private int key;
  private HistoryTrxResponse trx;
}

然后回到正常的json:

public class HistoryTrxResponse {
   private String trx_id;
   ...
   private int operation_id;
}

仍然需要一种方法将列表转换回Map,但它非常接近,并且内部数据被解析/反序列化。

廉飞捷
2023-03-14

您希望MapJSON端由JSON Object表示,但有一个JSON Array可以默认映射到ListSetarray。我建议使用List

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;

import java.io.File;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class JsonPathApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = JsonMapper.builder().build();
        Values values = mapper.readValue(jsonFile, Values.class);
        System.out.println(values.getValuesAsMap());
    }
}

class Values {

    private String name;
    private List<List<BigDecimal>> values;

    public Map<BigDecimal, BigDecimal> getValuesAsMap() {
        return values.stream().collect(Collectors.toMap(
                k -> k.get(0),
                v -> v.get(1),
                (u, v) -> {
                    throw new IllegalStateException(String.format("Duplicate key %s", u));
                },
                LinkedHashMap::new));
    }

    // getters, setters, toString
}

以上代码打印:

{0.00207760=18.48000000, 0.00207740=40.00000000, 0.00207710=2.26000000}

在其他情况下,您需要为Map实现自定义反序列化程序,并使用@JsonDeserialize注释将其注册到该字段。

 类似资料:
  • 问题内容: 我正在创建具有嵌套列表的API。杰克逊似乎是创建对象的好工具,但我还不太清楚如何嵌套列表,我想知道它是否可能。 我的对象看起来像这样。 我希望有一种将其映射到看起来像这样的json的方法: 我们希望能够做到这一点,因此我们可以将属性添加到列表中。 问题答案: 您可以为编写自定义解串器。请参见以下示例: 现在,您必须通知Jackson将其用于您的财产。您可以通过以下方式执行此操作:

  • 问题内容: 这是我的Java代码,用于反序列化,我正在尝试将json字符串转换为java对象。为此,我使用了以下代码: 和我的product.java类 我收到以下错误。 帮我解决这个问题 问题答案: 似乎您正在尝试从JSON读取一个实际描述数组的对象。Java对象使用花括号映射到JSON对象,但是您的JSON实际上以方括号指定一个数组开始。 您实际拥有的是一个。为了描述泛型类型,由于Java的类

  • 问题内容: 我正在尝试使用Jakson反序列化嵌套的多态类型。意思是我的顶级类型引用了另一个多态类型,该类型最终由不是抽象的类扩展。这不起作用,并引发异常。 这是我要尝试做的简化示例。 我得到有关抽象类型的标准例外。 让我解释一下我的用例。我有一个描述数据工作流程的Json文档。我在“一级”有一个抽象类型,描述了对单个值的操作。我派生了一堆不是抽象的类,它们实现了常见的操作(我用@JsonSubT

  • 问题内容: 我有一些要映射到我的对象的JSON : 我的对象看起来像: 这是我的代码: 我不断收到此错误: 我在网上找到的所有示例都只是将JSON反序列化为带有少量或成员变量的简单POJO 。如何正确地将JSON映射到我的字段并使其行为正确? 我以为一旦工作成功就会返回,而会返回另一个(或)。我对使用Jackson还是很陌生,所以这甚至可能都不是我想要做的正确方法。任何帮助,将不胜感激! 问题答案

  • 问题内容: 我有一个Java类,我对从JSON反序列化感兴趣。我已经配置了一个特殊的MixIn类,以帮助我进行反序列化。只有和实例变量与适当的getter和setter方法相结合。看起来像这样: 在我的测试客户端中,我执行以下操作,但是在编译时它当然不起作用,因为与类型不匹配有关。 我知道我可以通过创建一个仅包含一个“响应”对象的方法来缓解此问题,但是随后我将不得不为我想返回的每种类型创建这些有点

  • 问题内容: 我想要的示例代码: 问题答案: 使用Jackson Kotlin Module 当前版本,如果您导入完整的模块包或特定的扩展功能,则将提供所有扩展方法。如: 因此,用于Kotlin的Jackson模块将推断出正确的类型,并且您不需要实例。 因此,您的情况(稍微重命名并修复了数据类和JSON): 您也可以使用以下形式: 如果没有导入,则会出现错误,因为找不到扩展功能。