[英]JSON to Java Objects, best practice for modeling the json stream
我有一个JSON流由当前正在开发的服务器端C ++程序生成。 我已经得到了一个结果JSON的样本,我担心我将不得不手工解析json,我将无法使用GSON或Jackson等工具提供的普通类映射。
请看一下他们提供的以下(有些)人为的例子。 我关注的部分是具有不同参数的元数据“serie”数组。 键 - “键”例如仅存在于一个数组元素中。 这不会导致尝试将此数组映射到特定类的集合时出现问题吗?
最后,我担心“点”对象不相似。 我对JSON(作为一个老式的java swing开发人员)的理解非常有限,但“点”键值对可以不同的事实 - 是一个问题。
这个json流的整个想法是描述一个表,显示进度的方法,并提供一种从底层硬件中寻求“更多”的机制。 此外,如果您想知道为什么,我将与瘦客户端(HTML浏览器)共享此数据流。
所以我更正确,这不会轻易转换为java对象?
{
"abort": "abort;session=sessionname",
"data": {
"metadata": [
{
"protocol": "HTTP",
"serie": [
{
"name": "k1",
"description": "xDR ID",
"tooltip": "ASDR Unique Identifier - UiD",
"type": "int64",
"key": "1"
},
{
"name": "c1",
"description": "Answered",
"tooltip": "Request with Response",
"type": "bool"
},
{
"name": "c2",
"description": "Active",
"tooltip": "Session status: active or closed/down",
"type": "bool"
}
]
},
{
"protocol": "DNS",
"serie": [
{
"name": "k1",
"description": "xDR ID",
"tooltip": "ASDR Unique Identifier - UiD",
"type": "int64",
"key": "1"
},
{
"name": "k2",
"description": "Transaction ID",
"type": "int64",
"key": "1",
"display": "number"
},
{
"name": "k3",
"description": "Client",
"tooltip": "Source IP Address",
"type": "string",
"key": "1",
"display": "ip"
}
]
}
],
"summary": [
{
"timestamp": "1331192727",
"protocol": "HTTP",
"activity": "www.google.com",
"results": "OK",
"point": {
"k1": "1",
"c1": "true",
"c2": "true"
}
},
{
"timestamp": "1331192727",
"protocol": "DNS",
"activity": "www.google.com",
"results": "OK",
"point": {
"k1": "1",
"k2": "1.1.4.229"
}
}
]
},
"progress": {
"perc": "100"
},
"more": "13,39,1331192727,1331192760,27236,1.1.4.229,limit=1000,session=sessionname"
}
感谢您提供的任何建议。
-D Klotz
使用GSON,假设您要反序列化的类具有JSON中出现的所有名称的字段,则JSON中找不到的字段将保留为null:
https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects
“在反序列化时,JSON中缺少的条目导致将对象中的相应字段设置为null”
如果JSON中允许任意字段名称,事情会变得复杂一些 - 例如,如果Point允许c1,c2,... cn。 但您可以使用自定义反序列化器来处理此问题。
https://sites.google.com/site/gson/gson-user-guide#TOC-Writing-a-Deserializer
编辑:
以下是为Point编写自定义反序列化器的方法:
private class DateTimeDeserializer implements JsonDeserializer<Point> {
public Point deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
List<PointPart> parts = Lists.newArrayList();
for(Map.Entry<String,JsonElement> entry :
json.getAsJsonObject().entrySet()) {
char type = ;
int index = Integer.parseInt(entry.getKey().substring(1)) - 1;
while(parts.size() <= index) {
parts.add(new PointPart());
}
PointPart part = parts.get(index);
switch(entry.getKey().charAt(0)) {
case 'c':
part.c = entry.getValue().getAsBoolean();
break;
case 'k':
part.k = entry.getValue().getAsInt();
break;
}
}
return new Point(parts);
}
}
class Point {
List<PointPart> parts;
Point(List<PointPart> parts) {
this.parts = parts;
}
}
class PointPart {
boolean c;
int k;
}
我更关心的是数据流中的元数据字段。 顶级“中止”和“更多”属性看起来像某种结构化字符串,您可能需要解析它们? 除此之外,您只需要使用从外部程序发送的最广泛的字段集来为每个Java对象建模。 您不必担心传输的数据是否缺少一个或多个字段,大多数JSON库只会在这种情况下反序列化null。 此外,大多数JSON库还允许您指定要忽略未知的传入字段。
因此,在为缺少字段反序列化null和忽略额外字段之间,您应该很好地进行解析。
不,这不是特别难以反序列化为Java对象。 JSON没有很多关于键入除基元之外的信息的线索。 通过查看要反序列化的对象或让用户提供要反序列化的对象,可以恢复对丢失类型信息的大多数担忧。 这正是flexjson的工作方式,并且您可以在每个点定义如何反序列化它。 它为大多数问题提供了合理的默认值,但您始终可以在JSON流中将ObjectFactory附加到特定的类或路径。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.