【问题标题】:Mapping JSON back to POJO with JSON and Jackson libs使用 JSON 和 Jackson 库将 JSON 映射回 POJO
【发布时间】:2012-12-28 01:39:47
【问题描述】:

我有一个 JSON 字符串:

{
    "fruit": {
        "weight":"29.01",
        "texture":null
    },
    "status":"ok"
}

...我正在尝试映射回 POJO:

public class Widget {
    private double weight; // same as the weight item above
    private String texture; // same as the texture item above

    // Getters and setters for both properties
}

上面的字符串(我正在尝试映射)实际上包含在org.json.JSONObject 中,可以通过调用该对象的toString() 方法获得。

我想使用Jackson JSON object/JSON 映射框架来做这个映射,到目前为止这是我最好的尝试:

try {
    // Contains the above string
    JSONObject jsonObj = getJSONObject();

    ObjectMapper mapper = new ObjectMapper();
    Widget w = mapper.readValue(jsonObj.toString(), Widget.class);

    System.out.println("w.weight = " + w.getWeight());
} catch(Throwable throwable) {
    System.out.println(throwable.getMessage());
}

不幸的是,当执行 Jackson readValue(...) 方法时,这段代码会引发异常:

Unrecognized field "fruit" (class org.me.myapp.Widget), not marked as ignorable (2 known properties: , "weight", "texture"])
    at [Source: java.io.StringReader@26c623af; line: 1, column: 14] (through reference chain: org.me.myapp.Widget["fruit"])

我需要映射器:

  1. 完全忽略外部大括号(“{”和“}”)
  2. fruit 更改为Widget
  3. 完全忽略status

如果唯一的方法是调用JSONObjecttoString() 方法,那就这样吧。但我想知道 Jackson 是否带有任何已经与 Java JSON 库一起使用的“开箱即用”的东西?

无论如何,编写 Jackson 映射器是我的主要问题。谁能发现我哪里出错了?提前致谢。

【问题讨论】:

  • 你似乎认为你有一个对象......你没有。您的 JSON 表示(并将映射到)具有“fruit”字段(包含包含其他两个字段的对象)和“status”字段的对象。
  • 那么就没有办法将映射器配置为忽略/别名字段吗?这在带有 Castor 和 XStream 的 XML 领域是可能的。我想我只是假设在 JSON/Jackson-land 中也是如此。毕竟,isn't that what mapping is supposed to achieve?有多少数据库表完美映射回 POJO?如果像 Hibernate 这样的库不允许配置,它们就没有多大用处。
  • 但是......它确实映射正确。您正在尝试映射到与 JSON 对象不同的 对象。相关的是:stackoverflow.com/a/13873443/302916 这是我对尝试做同样事情的人的回答,但使用的是 Gson。我没有在 Jackson 中使用自定义序列化/反序列化,但我确信有办法做到这一点。最简单的解决方案就是像该答案中的最后一个示例一样创建一个内部类。
  • 为什么weigth 在你的 JSON 中是一个字符串,而在你的 POJO 中是一个双精度值?
  • @fge - 我无法控制收到的 JSON,但 POJO 必须是双精度的。

标签: java json jackson


【解决方案1】:

您需要有一个类 PojoClass,其中包含 (has-a) Widget 实例,称为 fruit

在你的映射器中试试这个:

    String str = "{\"fruit\": {\"weight\":\"29.01\", \"texture\":null}, \"status\":\"ok\"}";
    JSONObject jsonObj = JSONObject.fromObject(str);
    try
    {
        // Contains the above string

        ObjectMapper mapper = new ObjectMapper();
        PojoClass p = mapper.readValue(jsonObj.toString(), new TypeReference<PojoClass>()
        {
        });

        System.out.println("w.weight = " + p.getFruit().getWeight());
    }
    catch (Throwable throwable)
    {
        System.out.println(throwable.getMessage());
    }

这是你的Widget 班级。

public class Widget
{    private double weight;
     private String texture;
    //getter and setters.
}

这是你的PojoClass

public class PojoClass
{
    private Widget fruit;
    private String status;
    //getter and setters.
}

【讨论】:

  • 这条线JSONObject jsonObj = JSONObject.fromObject(str);实际上做了什么?
  • 如果 jackson 库已经具备将 java 对象从 JSON 转换为 JSON 所需的一切,为什么我必须使用来自 org.jsonJSONObject 和来自 jacksonObjectMappermkyong.com/java/how-to-convert-java-object-to-from-json-jackson
  • @MagnoC - 随意编辑答案。答案本身已经超过 4 年了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
相关资源
最近更新 更多