我从JavaScript / Ruby开始使用Java。假设我有一个动物的以下JSON对象:
{
name: {
common: "Tiger",
latin: "Panthera tigris"
}
legs: 4
}
我正在处理许多动物API,我想将它们标准化为我自己的通用格式,例如:
{
common_name: "Tiger",
latin_name: "Panthera tigris",
limbs: {
legs: 4,
arms: 0
}
}
在JavaScript中,这很简单:
normalizeAnimal = function(original){
return {
common_name: original.name.common,
latin_name: original.name.latin,
limbs: {
legs: original.legs || 0,
arms: original.arms || 0
}
}
}
但是在Java中呢?使用org.json中的JSONObject类,我可以继续做这样的事情:
public JSONObject normalizeAnimal(JSONObject original) throws JSONException{
JSONObject name = original.getJSONObject("name");
JSONObject limbs = new JSONObject();
JSONObject normalized = new JSONObject();
normalized.put("name_name", name.get("common"));
normalized.put("latin_name", name.get("latin"));
try{
limbs.put("legs", original.get("legs");
}catch(e){
limbs.put("legs", 0);
};
try{
limbs.put("arms", original.get("arms");
}catch(e){
limbs.put("arms", 0);
};
normalized.put("limbs", limbs);
return normalized;
}
随着我正在处理的JSON对象变得越来越深,这变得更糟。除了这一切之外,我正在处理动物对象的许多提供者,我最终会寻找一些简洁的配置格式来描述转换(例如,可能,"common_name": "name.common", "limbs.legs": "legs"
)。
我如何在Java中减少这种麻烦?
答案 0 :(得分:6)
使用像Gson或Jackson这样的库,并将JSON映射到Java对象。
所以你会有一个类似
的beanpublic class JsonAnima {
private JsonName name;
private int legs;
}
public class JsonName {
private String commonName;
private String latinName;
}
可以使用类似(使用Jackson)的任何库轻松转换
ObjectMapper mapper = new ObjectMapper();
JsonAnimal animal = mapper.readValue(jsonString, JsonAnimal.class);
然后你可以创建一个“转换器”来将JsonAnimal映射到Animal类。
这可以是一种方法。 :)
一些链接:
答案 1 :(得分:1)
如果您将这个用于许多不同类型的对象,我建议使用反射而不是手动序列化每个对象。通过使用反射,您不需要创建像normalizeAnimal这样的方法,只需创建一个方法或一个类来执行序列化为json格式。
如果你搜索“映射json java”,你会发现一些有用的参考资料。像gson一样。以下是他们网站上的一个示例:
class BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
BagOfPrimitives() {
// no-args constructor
}
}
//(Serialization)
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);
///==> json is {"value1":1,"value2":"abc"}
///Note that you can not serialize objects with circular references since that will result in infinite recursion.
//(Deserialization)
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
//==> obj2 is just like obj
答案 2 :(得分:1)
纯Java解决方案都面临着处理源数据不可靠结构的挑战。如果您在JVM中运行,我建议您考虑使用Groovy来执行Parse和构建源JSON。结果看起来很像上面概述的Javascript解决方案:
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
def originals = [
'{ "name": { "common": "Tiger", "latin": "Panthera tigris" }, "legs": 4 }',
'{ "name": { "common": "Gecko", "latin": "Gek-onero" }, "legs": 4, "arms": 0 }',
'{ "name": { "common": "Liger" }, "legs": 4, "wings": 2 }',
'{ "name": { "common": "Human", "latin": "Homo Sapien" }, "legs": 2, "arms": 2 }'
]
originals.each { orig ->
def slurper = new JsonSlurper()
def parsed = slurper.parseText( orig )
def builder = new JsonBuilder()
// This builder looks a lot like the Javascript solution, no?
builder {
common_name parsed.name.common
latin_name parsed.name.latin
limbs {
legs parsed.legs ?: 0
arms parsed.arms ?: 0
}
}
def normalized = builder.toString()
println "$normalized"
}
运行上面的脚本处理“锯齿状”JSON(并非所有元素都具有相同的属性)和输出如...
{"common_name":"Tiger","latin_name":"Panthera tigris","limbs":{"legs":4,"arms":0}}
{"common_name":"Gecko","latin_name":"Gek-onero","limbs":{"legs":4,"arms":0}}
{"common_name":"Liger","latin_name":null,"limbs":{"legs":4,"arms":0}}
{"common_name":"Human","latin_name":"Homo Sapien","limbs":{"legs":2,"arms":2}}
答案 3 :(得分:0)
您可以尝试少量jmom Java库
JsonValue json = JsonParser.parse(stringvariablewithjsoninside);
Jmom mom = Jmom.instance()
.copy("/name/common", "/common_name", true)
.copy("/name/latin", "/latin_name", true)
.copy("/arms", "/limbs/arms", true)
.copy("/legs", "/limbs/legs", true)
.remove("/name")
;
mom.apply(json);
String str = json.toPrettyString(" ");