这个问题以前肯定有人问过,但我找不到。
我正在使用第三方库来检索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?
发布于 2013-12-21 03:43:40
由于您有一些JSON数据的抽象表示(一个org.json.JSONObject
对象),并且您计划使用Jackson库--该库有自己的JSON数据抽象表示(com.fasterxml.jackson.databind.JsonNode
) --那么从一种表示到另一种表示的转换将使您避免解析-序列化-解析过程。因此,不使用接受String
的readValue
方法,而是使用接受JsonParser
的this version
JSONObject jsonObject = //...
JsonNode jsonNode = convertJsonFormat(jsonObject);
ObjectMapper mapper = new ObjectMapper();
MyPojoClass myPojo = mapper.readValue(new TreeTraversingParser(jsonNode), MyPojoClass.class);
convertJsonFormat
是一种非常简单的格式,因此手动创建JSON应该不难。这是我的尝试:
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
可以表示的所有内容。
发布于 2019-12-06 15:36:35
更简单的方法是使用Gson。
JSONObject jsonObject = //...
PojoObject objPojo = new Gson().fromJson(jsonObject.toString(), PojoObject.class);
这对我很有效。
https://stackoverflow.com/questions/20534862
复制相似问题