当前位置: 首页 > 面试题库 >

如何有效地将org.json.JSONObject映射到POJO?

洪鸿博
2023-03-14
问题内容

这个问题一定是以前问过的,但是我找不到。

我正在使用第3方库来检索JSON格式的数据。图书馆将数据作为数据提供给我org.json.JSONObject。我想将此映射JSONObject到POJO(普通Java对象)以简化访问/代码。

对于映射,我目前ObjectMapper以这种方式使用Jackson图书馆中的:

JSONObject jsonObject = //...
ObjectMapper mapper = new ObjectMapper();
MyPojoClass myPojo = mapper.readValue(jsonObject.toString(), MyPojoClass.class);

据我所知,上述代码可以得到显着优化,因为当前JSONObject已经解析的中的数据将再次通过方法馈入序列化-
反序列化链,JSONObject.toString()然后再馈入ObjectMapper

我想避免这两次转换(toString()和解析)。有没有一种方法可以使用将JSONObject其数据直接映射到POJO?


问题答案:

由于您具有一些JSON数据(org.json.JSONObject对象)的抽象表示,并且您打算使用拥有自己的JSON数据抽象表示形式(Jackson)的Jackson库,因此com.fasterxml.jackson.databind.JsonNode从一种表示形式转换为另一种表示形式将使您从解析序列化解析过程。因此,您可以使用接受a的此版本,而不是使用readValue接受a
的方法:StringJsonParser

JSONObject jsonObject = //...
JsonNode jsonNode = convertJsonFormat(jsonObject);
ObjectMapper mapper = new ObjectMapper();
MyPojoClass myPojo = mapper.readValue(new TreeTraversingParser(jsonNode), MyPojoClass.class);

JSON是一种非常简单的格式,因此convertJsonFormat手动创建它并不难。这是我的尝试:

static JsonNode convertJsonFormat(JSONObject json) {
    ObjectNode ret = JsonNodeFactory.instance.objectNode();

    @SuppressWarnings("unchecked")
    Iterator<String> iterator = json.keys();
    for (; iterator.hasNext();) {
        String key = iterator.next();
        Object value;
        try {
            value = json.get(key);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
        if (json.isNull(key))
            ret.putNull(key);
        else if (value instanceof String)
            ret.put(key, (String) value);
        else if (value instanceof Integer)
            ret.put(key, (Integer) value);
        else if (value instanceof Long)
            ret.put(key, (Long) value);
        else if (value instanceof Double)
            ret.put(key, (Double) value);
        else if (value instanceof Boolean)
            ret.put(key, (Boolean) value);
        else if (value instanceof JSONObject)
            ret.put(key, convertJsonFormat((JSONObject) value));
        else if (value instanceof JSONArray)
            ret.put(key, convertJsonFormat((JSONArray) value));
        else
            throw new RuntimeException("not prepared for converting instance of class " + value.getClass());
    }
    return ret;
}

static JsonNode convertJsonFormat(JSONArray json) {
    ArrayNode ret = JsonNodeFactory.instance.arrayNode();
    for (int i = 0; i < json.length(); i++) {
        Object value;
        try {
            value = json.get(i);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
        if (json.isNull(i))
            ret.addNull();
        else if (value instanceof String)
            ret.add((String) value);
        else if (value instanceof Integer)
            ret.add((Integer) value);
        else if (value instanceof Long)
            ret.add((Long) value);
        else if (value instanceof Double)
            ret.add((Double) value);
        else if (value instanceof Boolean)
            ret.add((Boolean) value);
        else if (value instanceof JSONObject)
            ret.add(convertJsonFormat((JSONObject) value));
        else if (value instanceof JSONArray)
            ret.add(convertJsonFormat((JSONArray) value));
        else
            throw new RuntimeException("not prepared for converting instance of class " + value.getClass());
    }
    return ret;
}

需要注意的是,虽然杰克逊的JsonNode可以代表一些额外的类型(如BigIntegerDecimal等),它们是没有必要的,因为上面涵盖了该代码JSONObject可以代表。



 类似资料:
  • contiki os如何将IP地址映射到MAC地址,该地址存储在哪里? 我知道ICMPv6和RPL的基础知识,但是一旦网络建成,在发送IPv6数据包时,如何知道下一跳的MAC地址?我假设不是每次都发送邻居请求消息。此外,在Cooja上,我看到的唯一ICMPv6消息是RPL消息。 我试图通过grep、谷歌搜索和文档找到答案,但我找不到。

  • 问题内容: 我想将a存储在列中并保持不变。这两个和是“本地”类型的定义。因此, 时区 的概念不应以任何方式干涉。 下面的代码是一个最小示例,该示例在内存数据库中创建带有列的表。Maven工件必须在类路径中。 首先,定义方法和: 请注意,该方法使用单引号引起来的值,因此Java™没有机会创建时区歧义。现在,一次调用几次,每次使用不同的时区设置: 然后打印以下内容: 假设数据库表未更改,如何编写该方法

  • 我正在用Stream学习Java,我有一张

  • 问题内容: 我在了解如何实现这一目标方面遇到了问题。 基本上我们有一个API,用户发送以下格式的JSON :(如果代码不完美,请原谅,但您可以理解) 好的,我不确定我是否正确设置了JSON格式,但是现在这是我的问题。 我有一个带有参数Name,Last的类,还有一个作为其成员之一的对象Client和Property Date。 像这样: 因此,基本上,我不确定如何获取JSON,然后将其映射到我的对

  • 本文向大家介绍Django如何将URL映射到视图,包括了Django如何将URL映射到视图的使用技巧和注意事项,需要的朋友参考一下 前言 URLconf 就像是 Django 所支撑网站的目录。它的本质是 URL 模式以及要为该 URL 模式调用的视图函数之间的映射表。你就是以这种方式告诉 Django,对于这个 URL 调用这段代码,对于那个 URL 调用那段代码。但必须记住的是视图函数必须位于

  • 我有一个带有域类的Grails项目。这个持久类应该映射到JavaDTO。我在这里发现了一个非常旧的Grails插件,它并没有真正解决这个问题。 是否有一个插件或方法: 注释映射到相应DTO类的域类属性