如何使用flexjson以优雅的方式反序列化此JSON



我正在使用Oracle OPAM,它有一个REST API,它有类似以下的方法

{
"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这种繁琐的方法来解析这个REST API

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);

这显然有效,但它有很多括号,这让我想起了LISP。

如果我们只使用POJO会更好(如果我可以通过一些GUI工具自动生成,那就更好了,但我知道我要求太多了,我们生活在2014年)。

我知道这里有一些关于如何映射属性的文档:http://flexjson.sourceforge.net/#Deserialization但我真的希望他们有一些真正复杂的示例(包括JSON——在文档中没有任何JSON示例的情况下解释如何反序列化有什么用?)

这个问题显然不是什么新鲜事,但像1、2或3这样的相关问题似乎也在等待答案。

(附言,除了这个似乎有一些我可以使用的信息)

所以我的问题是:我如何用FlexJSON将这个JSON解析成一个不仅仅由Maps组成的结构

没有任何Map:的工作解决方案

让我们定义类自下而上

1.目标:


public class Target {
private String uri;
private String type;
private String name;
private String host;
private String domain;
private String description;
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

此类表示以下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"
}

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"
}
}

3.RestApiRespons

这个类表示您的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;
}
}

4.让我们测试一下

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"
}
}
]
}

我希望它能有所帮助。

哦,看看这个

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
}

其中

public class MetaTarget {
private Target target;
public Target getTarget() {
return target;
}
public void setTarget(Target target) {
this.target = target;
}
}

public class Target {
/**
* uri is the target resource URI.
*/
private String  uri;
/**
* type is the target type.
*/
private String  type;
/**
* hostname is the target's host name.
*/
private String  hostname;
/**
* name is the target name.
*/
private String  name;
/**
* org is the target's organization.
*/
private String  org;
/**
* domain is the target's domain.
*/
private String  domain;
/**
* description is a description of the target system.
*/
private String  description;
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOrg() {
return org;
}
public void setOrg(String org) {
this.org = org;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Target [uri=" + uri + ", type=" + type + ", hostname=" + hostname + ", name=" + name + ", org=" + org + ", domain=" + domain + ", description=" + description + "]";
}
}

更少的地图!

最新更新