【问题标题】:How to deserialize nested JSON array into a Map using Java's Jackson library?如何使用 Java 的 Jackson 库将嵌套的 JSON 数组反序列化为 Map?
【发布时间】:2019-11-29 22:43:42
【问题描述】:

我有这样的结构:

{
    "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 来实现?

谢谢!

爱德华多

【问题讨论】:

    标签: java json jackson deserialization json-deserialization


    【解决方案1】:

    您期望MapJSON 一侧由JSON Object 表示,但有一个JSON Array 默认可以映射到ListSetarray。我建议在POJO 中使用List&lt;List&lt;BigDecimal&gt;&gt; 并创建一个将数据转换为Map 的方法:

    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 实现custom 反序列化器,并使用@JsonDeserialize 注释为该字段注册它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多