我有一个嵌套的json,其中在最里面的数组中有一些键,其键值可以是字符串数组或字符串数组。 json格式不一致。如何使用gson解析此类json。
我试图编写一个自定义反序列化器(请参阅Gson - parsing json with field that is array or string),但这甚至在我可以将属性检测为字符串或数组然后相应地更新属性之前就抛出了异常。
我的json就是这样
{
"hits" : {
"total" : 100,
"max_score" : 1,
"hits": [
{"_index": "s1",
"_source":{
"activeOrExpired":[
["active"]
]
}
},
{"_index": "s1",
"_source":{
"activeOrExpired":[
"expired"
]
}
}
]
}
}
我的java类是
public class OuterJson {
@SerliazedName("hits")
public Hits hitsOuter;
public static class Hits {
public List<InnerHits> innerHits;
}
}
public InnerHits {
public String _index;
public Source _source;
public static class Source {
public List<List<String>> activeOrExpired;//I declare this field as
//list of list of strings
public Source() {
activeOrExpired = new ArrayList<>();
}
}
}
public class CustomDeserializer implements JsonDeserializer<OuterJson> {
@Override
public OuterJson deserialize(JsonElement elem, Type type, JsonDeserializationContext context) throws JsonParseException {
JsonObject outerObj = elem.getAsJsonObject();
JsonElement innerHits = outerObj.get("hits").getAsJsonObject().get("hits");
//I want to then detect the type of "activeOrExpired" and convert it
//to list of list of strings if it is present just as a string
//I am getting exception in the below line
InnerHits[] innerHitsArray = new Gson().fromJson(innerHits, InnerHits[].class);
//omitting below code for brevity since my code is failing above itself.
}
}
例外是
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was String at path $[0]._source.activeOrExpired[0]
在此,最里面的“ hits”数组具有“ _source”数组,该数组具有一个字段“ activeOrExpired”,该字段以字符串数组或字符串数组的形式出现。 我应该如何设计自定义解串器来处理这种情况? 我是gson的新手,并遵循上面链接中提到的方法。我的代码已在上面进行了描述,任何人都可以给我一些进展的提示。谢谢!
答案 0 :(得分:0)
您可以将DSM流解析库用于这种复杂的JSON或XML。通过使用DSM,您无需创建Java存根文件即可进行反序列化。您可以直接反序列化到自己的班级。 它使用基于YAML的映射文件。
这是您问题的解决方案。我不确定您的对象结构。我只反序列化其中的一部分。
映射文件:
result:
type: object # result is map.
path: /hits
fields:
hits:
path: hits
type: array
fields:
index:
path: _index
source:
path: _source/activeOrExpired
filter: $value!=null
type: array # source is also array.
使用DSM 过滤JSON并反序列化。
// you can pass your class to deserialize directly to your class instead of getting map or list as a result.
//DSM dsm=new DSMBuilder(new File("path/to/maping.yaml")).create(YourClass.class);
DSM dsm=new DSMBuilder(new File("path/to/maping.yaml")).create();
Map<String,Object> hits= (Map<String,Object>)dsm.toObject(new File("path/to/data.json");
匹配变量的json表示形式
{
"innerHits" : [ {
"index" : "s1",
"source" : [ "active" ]
}, {
"index" : "s1",
"source" : [ "expired" ]
} ]
}