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

标签 java json mapping jackson mapper

我正在使用第 3 方库来检索 JSON 格式的数据。该库以 org.json.JSONObject 的形式向我提供数据。我想将此 JSONObject 映射到 POJO (Plain Old Java Object)更简单的访问/代码。

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

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 对象)的抽象表示,并且您计划使用 Jackson 库 - 它有自己的 JSON 数据抽象表示(com.fasterxml.jackson.databind.JsonNode) - 然后从一种表示另一种表示将使您免于解析-序列化-解析过程。因此,不要使用接受 StringreadValue 方法,而是使用 this version接受 JsonParser:

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;
}

请注意,虽然 Jackson 的 JsonNode 可以表示一些额外的类型(例如 BigIntegerDecimal 等),但它们不是必需的,因为上面的代码涵盖了 JSONObject 可以表示的所有内容。

关于java - 如何有效地将 org.json.JSONObject 映射到 POJO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20534862/

相关文章:

java - 如何在不创建帐户的情况下直接将联系人添加到组中?

json4s:使用自定义序列化程序反序列化特定字段

javascript遍历json对象

r - 数据表映射

java - 如何在 XML-RPC 响应成员中指定数据类型?

java - 无法从我的自定义布局类调用方法

java - 解析Android应用程序发送的JSON数据

mapping - 在 Doctrine 2 中使用 onDelete

c++ - 通过着色器的 OpenGL 投影纹理映射

java - 当 JFrame 调整大小时,JTable 列可能不会调整大小