杰克逊无法将JSON映射到包含地图的对象

时间:2022-02-22 18:02:10

I have a Java POJO like so:

我有一个像这样的Java POJO:

public class Widget {
    private Map<String,Object> params;

    // Getter, setter, ctor, etc...
}

I have a method that currently receives a JSON String, and is attempting to use Jackson's ObjectMapper to map that JSON into a Widget instance:

我有一个当前接收JSON字符串的方法,并且正在尝试使用Jackson的ObjectMapper将该JSON映射到Widget实例:

public Widget fromJSON(String json) {
    ObjectMapper jsonMapper = new ObjectMapper();
    return jsonMapper.readValue(json, Widget.class);
}

Currently the JSON I'm passing in is:

目前我传入的JSON是:

{
    "params": [{
        "acks": "all"
    }, {
        "retries": 0
    }, {
        "batch.size": 16384
    }, {
        "linger.ms": 1
    }, {
        "buffer.memory": 33554432
    }, {
        "key.serializer": "org.apache.kafka.common.serialization.StringSerializer"
    }, {
        "value.serializer": "org.apache.kafka.common.serialization.StringSerializer"
    }]
}

When this runs I get the following exception:

当这运行时,我得到以下异常:

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance
    of java.util.LinkedHashMap out of START_ARRAY token

I see this other question addressing a very similar problem, except that question addresses using Jackson to map JSON to a Java Map, not an object (Widget) that contains a Java Map.

我看到另一个问题解决了一个非常类似的问题,除了问题地址使用Jackson将JSON映射到Java Map,而不是包含Java Map的对象(Widget)。

I've used http://jsonlint.com to verify that the JSON is valid. So I either need to change the JSON or the code, or possibly both. Any ideas?

我使用http://jsonlint.com来验证JSON是否有效。所以我需要更改JSON或代码,或者两者都需要。有任何想法吗?

2 个解决方案

#1


1  

The JSON is valid, but not for a Map. The value of params is an array, it should be an object like:

JSON有效,但不适用于Map。 params的值是一个数组,它应该是一个像这样的对象:

{
    "params": {
        "acks": "all",
        "retries": 0,
        "batch.size": 16384,
        "linger.ms": 1,
        "buffer.memory": 33554432,
        "key.serializer": "org.apache.kafka.common.serialization.StringSerializer",
        "value.serializer": "org.apache.kafka.common.serialization.StringSerializer"
    }
}

At Jackson Five Minutes you can find the following relation:

在Jackson Five Minutes,您可以找到以下关系:

Concrete Java types that Jackson will use for simple data binding are:

杰克逊将用于简单数据绑定的具体Java类型是:

╔══════════════════════╦══════════════════════════════╗
║      JSON Type       ║          Java Type           ║
╠══════════════════════╬══════════════════════════════╣
║ object               ║ LinkedHashMap<String,Object> ║
║ array                ║ ArrayList<Object>            ║
║ string               ║ String                       ║
║ number (no fraction) ║ Integer, Long or BigInteger  ║
║ number (fraction)    ║ Double (or BigDecimal)       ║
║ true|false           ║ Boolean                      ║
║ null                 ║ null                         ║
╚══════════════════════╩══════════════════════════════╝

#2


1  

A List<Map<String, Object>> should do the trick:

List >应该做的诀窍:

public class Widget {

    private List<Map<String, Object>> params;

    // Getter and setters ommited
}

#1


1  

The JSON is valid, but not for a Map. The value of params is an array, it should be an object like:

JSON有效,但不适用于Map。 params的值是一个数组,它应该是一个像这样的对象:

{
    "params": {
        "acks": "all",
        "retries": 0,
        "batch.size": 16384,
        "linger.ms": 1,
        "buffer.memory": 33554432,
        "key.serializer": "org.apache.kafka.common.serialization.StringSerializer",
        "value.serializer": "org.apache.kafka.common.serialization.StringSerializer"
    }
}

At Jackson Five Minutes you can find the following relation:

在Jackson Five Minutes,您可以找到以下关系:

Concrete Java types that Jackson will use for simple data binding are:

杰克逊将用于简单数据绑定的具体Java类型是:

╔══════════════════════╦══════════════════════════════╗
║      JSON Type       ║          Java Type           ║
╠══════════════════════╬══════════════════════════════╣
║ object               ║ LinkedHashMap<String,Object> ║
║ array                ║ ArrayList<Object>            ║
║ string               ║ String                       ║
║ number (no fraction) ║ Integer, Long or BigInteger  ║
║ number (fraction)    ║ Double (or BigDecimal)       ║
║ true|false           ║ Boolean                      ║
║ null                 ║ null                         ║
╚══════════════════════╩══════════════════════════════╝

#2


1  

A List<Map<String, Object>> should do the trick:

List >应该做的诀窍:

public class Widget {

    private List<Map<String, Object>> params;

    // Getter and setters ommited
}