如何有效地将org.json.JSONObject映射到POJO?
这个问题一定是以前问过的,但是我找不到。
我正在使用第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
的方法:String
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;
}
需要注意的是,虽然杰克逊的JsonNode
可以代表一些额外的类型(如BigInteger
,Decimal
等),它们是没有必要的,因为上面涵盖了该代码JSONObject
可以代表。
以上是 如何有效地将org.json.JSONObject映射到POJO? 的全部内容, 来源链接: utcz.com/qa/400780.html