Java 如何使用flexjson以优雅的方式反序列化此JSON
我正在使用OracleOpam,它有一个RESTAPI,它有这样的方法Java 如何使用flexjson以优雅的方式反序列化此JSON,java,json,wadl,json-deserialization,Java,Json,Wadl,Json Deserialization,我正在使用OracleOpam,它有一个RESTAPI,它有这样的方法 { "Target Collection":[ { "target":{ "uri":"https:\/\/opam_server_host:opam_ssl_port\/opam\/target\ /9bbcbbb087174ad1900ea691a2573b61", "type":"ldap", "name":"perso
{
"Target Collection":[
{
"target":{
"uri":"https:\/\/opam_server_host:opam_ssl_port\/opam\/target\
/9bbcbbb087174ad1900ea691a2573b61",
"type":"ldap",
"name":"person1-ldap",
"host":"opam_server_host",
"domain":"berkeley"
"description" : "Ldap target"
}
},
{
"target":{
"uri":"https:\/\/opam_server_host:opam_ssl_port\/opam\/target\
/ac246a162ce948c7b1cdcc17dfc92c15",
"type":"ldap",
"name":"person1-ldap2",
"host":"opam_server_host:opam_ssl_port",
"domain":"berkeley"
"description" : "Ldap target"
}
}
]
}
我正在使用FlexJSON来反序列化这些实体。如果可以的话,我会使用ApacheCXF为我生成bean,但问题是WADL使用的是无效的https证书+基本身份验证,让wadl2java在这些条件下工作所花费的时间比我希望的要多(可惜它不是WSDL,所以我可以从eclipse内部快速轻松地创建存根)
因此,我使用flexjson的这种繁琐方法来解析这个RESTAPI
JSONDeserializer<Map<String,List<Map<String,Map<String,String>>>>> json = new JSONDeserializer<>();
Map<String,List<Map<String,Map<String,String>>>> targetCollection = json.deserialize(new InputStreamReader(content));
List<Map<String,Map<String,String>>> col = targetCollection.get("Target Collection"); Map<String,Map<String,String>> keyVal = col.get(0);
Map<String,String> targetVal = keyVal.get("target");
System.out.println(targetVal);
JSONDeserializer json=新的JSONDeserializer();
Map targetCollection=json.deserialize(新的InputStreamReader(内容));
List col=targetCollection.get(“目标集合”);Map keyVal=col.get(0);
Map targetVal=keyVal.get(“目标”);
系统输出打印项次(targetVal);
这显然是可行的,但它有这么多括号,让我想起了LISP
如果我们可以用POJO来代替,那就更好了(如果我可以用一些GUI工具自动生成,那就更好了,但我知道我要求太多了,我们生活在2014年)
我知道这里有一些关于如何映射属性的文档:但我真的希望他们有一些真正复杂的示例(包括JSON-在文档中没有任何JSON示例的情况下解释如何反序列化有什么用?)
这个问题显然不是新问题,但似乎相关的问题如,或也在等待答案
(注意,除了一个似乎有一些信息我可以使用)
所以我的问题是:我如何用FlexJSON将这个JSON解析成一个不仅由地图构成的结构?哦,看看这个
JSONDeserializer<Map<String,List<MetaTarget>>> j = new JSONDeserializer<>();
List<MetaTarget> l = j.use("values.values", MetaTarget.class) //magic that means that the item inside a list (values #1) inside a map (values #2) is a MetaTarget
.deserialize(new InputStreamReader(JSONParser.class.getResourceAsStream("sample.json")),Map.class) //have no idea what Map does here
.get("Target Collection"); //since deserializer returns a map, use this get to return a map value, in this case, a List
for(MetaTarget mt : l){
System.out.println(mt.getTarget());
mt.getTarget().getHostname(); //I can access the attribute... thanks god
}
及
少点地图 无任何
映射的工作解决方案
:
让我们自下而上定义类:
1。目标:
此类表示以下JSON:
"target": {
"uri": "https://opam_server_host:opam_ssl_port/opam/target/9bbcbbb087174ad1900ea691a2573b61",
"type": "ldap",
"name": "person1-ldap",
"host": "opam_server_host",
"domain": "berkeley",
"description": "Ldap target"
}
{
"target": {
"uri": "https://opam_server_host:opam_ssl_port/opam/target/9bbcbbb087174ad1900ea691a2573b61",
"type": "ldap",
"name": "person1-ldap",
"host": "opam_server_host",
"domain": "berkeley",
"description": "Ldap target"
}
}
2。目标说话者: 请注意,
target
它位于大括号内。这个类只是简单地包装它
public class TargetWrapper {
private Target target;
public Target getTarget() {
return target;
}
public void setTarget(Target target) {
this.target = target;
}
}
此类表示以下JSON:
"target": {
"uri": "https://opam_server_host:opam_ssl_port/opam/target/9bbcbbb087174ad1900ea691a2573b61",
"type": "ldap",
"name": "person1-ldap",
"host": "opam_server_host",
"domain": "berkeley",
"description": "Ldap target"
}
{
"target": {
"uri": "https://opam_server_host:opam_ssl_port/opam/target/9bbcbbb087174ad1900ea691a2573b61",
"type": "ldap",
"name": "person1-ldap",
"host": "opam_server_host",
"domain": "berkeley",
"description": "Ldap target"
}
}
3。RestApiResponse 此类表示api返回的整个
JSON
public class RestApiResponse {
@JSON(name="Target Collection")
private List<TargetWrapper> targetCollection = new ArrayList<TargetWrapper>();
@JSON(name="Target Collection")
public List<TargetWrapper> getTarget_Collection() {
return targetCollection;
}
@JSON(name="Target Collection")
public void setTarget_Collection(List<TargetWrapper> tc) {
this.targetCollection = tc;
}
}
我希望它能有所帮助。不仅仅是地图——那里至少有一个数组。@HotLicks true:-)但我想如果我们可以用POJO替换地图,列表就不会麻烦了,我发现
Map
更容易理解(和键入)。这个注释@JSON是什么?我明白了。。您正在使用flexjson 3.2@利奥,我没有注意到这个版本。你不能用那个版本吗?
public class RestApiResponse {
@JSON(name="Target Collection")
private List<TargetWrapper> targetCollection = new ArrayList<TargetWrapper>();
@JSON(name="Target Collection")
public List<TargetWrapper> getTarget_Collection() {
return targetCollection;
}
@JSON(name="Target Collection")
public void setTarget_Collection(List<TargetWrapper> tc) {
this.targetCollection = tc;
}
}
public static void main(String[] args) {
JSONDeserializer<RestApiResponse> js = new JSONDeserializer<RestApiResponse>();
String input="{\"Target Collection\":[{\"target\":{\"uri\":\"https://opam_server_host:opam_ssl_port/opam/target/9bbcbbb087174ad1900ea691a2573b61\",\"type\":\"ldap\",\"name\":\"person1-ldap\",\"host\":\"opam_server_host\",\"domain\":\"berkeley\",\"description\":\"Ldap target\"}},{\"target\":{\"uri\":\"https://opam_server_host:opam_ssl_port/opam/target/ac246a162ce948c7b1cdcc17dfc92c15\",\"type\":\"ldap\",\"name\":\"person1-ldap2\",\"host\":\"opam_server_host:opam_ssl_port\",\"domain\":\"berkeley\",\"description\":\"Ldap target\"}}]}";
RestApiResponse restApiResponse=js.deserialize(input,RestApiResponse.class);
System.out.println(new JSONSerializer()
.exclude("*.class").deepSerialize(restApiResponse));
}
{
"Target Collection": [
{
"target": {
"description": "Ldap target",
"domain": "berkeley",
"host": "opam_server_host",
"name": "person1-ldap",
"type": "ldap",
"uri": "https://opam_server_host:opam_ssl_port/opam/target/9bbcbbb087174ad1900ea691a2573b61"
}
},
{
"target": {
"description": "Ldap target",
"domain": "berkeley",
"host": "opam_server_host:opam_ssl_port",
"name": "person1-ldap2",
"type": "ldap",
"uri": "https://opam_server_host:opam_ssl_port/opam/target/ac246a162ce948c7b1cdcc17dfc92c15"
}
}
]
}