问题 如何使用Jackson将JSON反序列化为Map 成员变量?


我有一些JSON我想映射到我的 Box目的:

  {
      "created_date": "2015-11-11",
      "generation_date": "2015-11-12T20:35:00+0000",
      "values": {
          "MORNING": 13,
          "EVENING": 18,
          "NOON": 446,
          "NIGHT": "0.60.0"
      },
      "id": "12345"
  }

和我的 Box 对象看起来像:

public class Box {
    @JsonProperty
    Map<String, Object> json;

    public Box() {
        // Blank
    }

    // Getter and setter for `json` field
}

这是我的代码:

Box box = null;
// `JSON_STRING` below refers to a string of the above JSON
metricsPacket = new ObjectMapper().readValue(JSON_STRING, Box.class);

我一直收到这个错误:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "created_date" (class com.me.Box), not marked as ignorable (one known property: "json"])

我在网上找到的所有例子都只是将JSON反序列化为一个简单的POJO String 要么 int 成员变量。如何正确地将我的JSON映射到我的 json 字段并使其行为正常?

我想,一旦这个工作 json.get("id") 会回来的 12345 而 json.get("values") 会回来另一个 Map<String, Object> (要么 Map<String, String>)。我仍然是使用杰克逊的新手,所以这也可能不是我想做的事情的正确方法。任何帮助,将不胜感激!


1842
2017-11-13 00:00


起源



答案:


首先,解决你的问题。您正在尝试将JSON反序列化为没有JSON字符串中存在字段的类,因此它无法找到这些字段并返回异常。

您也可以执行以下操作:

ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue(JSON_STRING, new TypeReference<Map<String, String>>(){});
box.setJsonMap(map);

box将有一个setter来设置json映射

或者您可以将所有字段添加到Box POJO并使用 GSON 让这更容易!

例如。 Json - >对象

Gson gson = new Gson();
Box box = gson.fromJson(JSON_STRING, Box.class);

例如。对象 - > Json

Gson gson = new Gson();
String str = gson.toJson(mBox); //mBox is some box object

GSON将填充框内的所有字段以匹配JSON字符串中找到的键值对。如果您不想这样做,请忽略它,但这是另一种选择!


10
2017-11-13 00:41



TypeReference 同 import com.fasterxml.jackson.core.type.TypeReference; - JonyD
@ lucas-crawford,如果您稍后再次设置地图,则无需实例化地图。 - Marco Altieri


答案:


首先,解决你的问题。您正在尝试将JSON反序列化为没有JSON字符串中存在字段的类,因此它无法找到这些字段并返回异常。

您也可以执行以下操作:

ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue(JSON_STRING, new TypeReference<Map<String, String>>(){});
box.setJsonMap(map);

box将有一个setter来设置json映射

或者您可以将所有字段添加到Box POJO并使用 GSON 让这更容易!

例如。 Json - >对象

Gson gson = new Gson();
Box box = gson.fromJson(JSON_STRING, Box.class);

例如。对象 - > Json

Gson gson = new Gson();
String str = gson.toJson(mBox); //mBox is some box object

GSON将填充框内的所有字段以匹配JSON字符串中找到的键值对。如果您不想这样做,请忽略它,但这是另一种选择!


10
2017-11-13 00:41



TypeReference 同 import com.fasterxml.jackson.core.type.TypeReference; - JonyD
@ lucas-crawford,如果您稍后再次设置地图,则无需实例化地图。 - Marco Altieri


我认为你需要在构造函数中添加一个带注释的参数。例如,

public Box(@JsonProperty("json") Map<String, Object> json) {
    // TODO
}

0
2017-11-13 00:31