Dan*_* S. 28 java mapping json jackson mapper
以前一定要问过这个问题,但我找不到.
我正在使用第三方库来检索JSON格式的数据.图书馆向我提供数据org.json.JSONObject.我想将其映射JSONObject到POJO(Plain Old Java Object)以获得更简单的访问/代码.
对于映射,我目前ObjectMapper以这种方式使用Jackson库:
JSONObject jsonObject = //...
ObjectMapper mapper = new ObjectMapper();
MyPojoClass myPojo = mapper.readValue(jsonObject.toString(), MyPojoClass.class);
Run Code Online (Sandbox Code Playgroud)
据我所知,上面的代码可以得到显着的优化,因为目前JSONObject已经解析过的数据再次被送入序列化 - 反序列化链中,JSONObject.toString()然后进入ObjectMapper.
我想避免这两次转换(toString()和解析).有没有办法使用JSONObject它将数据直接映射到POJO?
mgi*_*nbr 28
由于您有一些JSON数据(一个org.json.JSONObject对象)的抽象表示,并且您计划使用Jackson库 - 它有自己的JSON数据(com.fasterxml.jackson.databind.JsonNode)的抽象表示- 然后从一个表示到另一个表示的转换将使您免于parse-serialize-parse进程.因此,而不是使用readValue接受的方法String,你会使用这个版本,它接受一个JsonParser:
JSONObject jsonObject = //...
JsonNode jsonNode = convertJsonFormat(jsonObject);
ObjectMapper mapper = new ObjectMapper();
MyPojoClass myPojo = mapper.readValue(new TreeTraversingParser(jsonNode), MyPojoClass.class);
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
需要注意的是,虽然杰克逊的JsonNode可以代表一些额外的类型(如BigInteger,Decimal等),它们是没有必要的,因为上面的代码覆盖了一切JSONObject可以代表.
Ste*_*gne 23
如果你没有与杰克逊联系,你可以使用方便的谷歌 - 戈森图书馆作为替代.它只需要一个罐子,使用起来非常简单:
将java对象转换为JSON字符串:
String json_string = new Gson().toJson(an_object);
Run Code Online (Sandbox Code Playgroud)
从JSON字符串创建java对象:
MyObject obj = new Gson().fromJson(a_json_string, MyObject.class);
Run Code Online (Sandbox Code Playgroud)
我不知道与杰克逊相比的性能,但它很难比这简单...... Gson是一个稳定且广泛使用的库.
请访问https://code.google.com/p/google-gson/
ara*_*nid 18
添加旧问题的答案,但......
杰克逊可以绑定到org.json类型.通常,它可以在它可以绑定的任何类型之间进行转换,通过有效(尽管不是实际)序列化为JSON和反序列化.
如果你注册了JsonOrgModule,你可以直接从ObjectMapper进行转换:
@Test
public void convert_from_jsonobject() throws Exception {
JSONObject obj = new JSONObject().put("value", 3.14);
ObjectMapper mapper = new ObjectMapper().registerModule(new JsonOrgModule());
PojoData data = mapper.convertValue(obj, PojoData.class);
assertThat(data.value, equalTo(3.14));
}
@Test
public void convert_to_jsonobject() throws Exception {
PojoData data = new PojoData();
data.value = 3.14;
ObjectMapper mapper = new ObjectMapper().registerModule(new JsonOrgModule());
JSONObject obj = mapper.convertValue(data, JSONObject.class);
assertThat(obj.getDouble("value"), equalTo(3.14));
}
public static final class PojoData {
public double value;
}
Run Code Online (Sandbox Code Playgroud)
我提到这是有效的序列化?这是真的,它将输入对象序列化为TokenBuffer,它表示JSON解析事件的流,但对构建字符串等的影响较小,因为它可以在很大程度上引用输入中的数据.然后它将此流提供给反序列化器以生成输出对象.
因此,它有点类似于将JSONObject转换为JsonNode的建议,但更为一般.无论它实际上是否更高效都需要进行测量:要么将JsonNode构造为中间体,要么构造TokenBuffer,这两种方式都没有开销.
小智 5
使用 Gson 更简单的方法。
JSONObject jsonObject = //...
PojoObject objPojo = new Gson().fromJson(jsonObject.toString(), PojoObject.class);
Run Code Online (Sandbox Code Playgroud)
这对我有用。
| 归档时间: |
|
| 查看次数: |
54869 次 |
| 最近记录: |