我有一个第三方api调用,它返回json数据,这是一个不同事件对象的数组,我不知道如何将这些数据转换为适当的对象。
json响应的示例如下:
[{
"id": 1,
"globalID": 1,
"time": "2017-11-27T17:18:04.111394052Z",
"type": "Starting",
"data": {
"home": "/Users/dir",
"myID": "ABCDEFG_12345"
}
}, {
"id": 2,
"globalID": 2,
"time": "2017-11-27T17:18:05.49296402Z",
"type": "StateChanged",
"data": {
"folder": "abc-123",
"from": "idle",
"to": "scanning"
}
}, {
"id": 12,
"globalID": 12,
"time": "2017-11-27T17:18:06.328173772Z",
"type": "FolderSummary",
"data": {
"folder": "abc-123",
"summary": {
"globalBytes": 17896,
"globalDeleted": 0,
"globalDirectories": 19,
"globalFiles": 3,
"globalSymlinks": 0,
"ignorePatterns": false,
"inSyncBytes": 17896,
"inSyncFiles": 3,
"invalid": "",
"localBytes": 17896,
"localDeleted": 0,
"localDirectories": 19,
"localFiles": 3,
"localSymlinks": 0,
"needBytes": 0,
"needDeletes": 0,
"needDirectories": 0,
"needFiles": 0,
"needSymlinks": 0,
"sequence": 68,
"state": "idle",
"stateChanged": "2017-11-27T17:18:06.328010456Z",
"version": 68
}
}
} ... ]
每个事件的“data”属性包含不同的属性。事件属性“type”定义事件的类型以及它将具有哪些数据属性。我创建了一个抽象事件类来存储共享属性。
@JsonIgnoreProperties(ignoreUnknown = true)
abstract public class AbstractEvent implements Serializable {
protected Integer id = null;
protected Integer globalID = null;
protected String time = null;
protected String type = null;
protected EventData data = null;
/**
* @return the id
*/
public Integer getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(Integer id) {
this.id = id;
}
/**
* @return the globalID
*/
public Integer getGlobalID() {
return globalID;
}
/**
* @param globalID the globalID to set
*/
public void setGlobalID(Integer globalID) {
this.globalID = globalID;
}
/**
* @return the time
*/
public String getTime() {
return time;
}
/**
* @param time the time to set
*/
public void setTime(String time) {
this.time = time;
}
/**
* @return the type
*/
public String getType() {
return type;
}
/**
* @param type the type to set
*/
public void setType(String type) {
this.type = type;
}
/**
* @return the data
*/
public EventData getData() {
return data;
}
/**
* @param data the data to set
*/
public void setData(EventData data) {
this.data = data;
}
}
我创建了一个表示数据属性的接口:
@JsonIgnoreProperties(ignoreUnknown = true)
public interface EventData {
}
因此,事件'StateChanged'的示例如下:
@JsonIgnoreProperties(ignoreUnknown = true)
public class StateChangedEvent extends AbstractEvent {
protected StateChangedEventData data = null;
/**
* @return the data
*/
public StateChangedEventData getData() {
return data;
}
/**
* @param data the data to set
*/
public void setData(StateChangedEventData data) {
this.data = data;
}
}
StateChangedEventData对象表示数据:
@JsonIgnoreProperties(ignoreUnknown = true)
public class StateChangedEventData implements Serializable, EventData
{
private String folder = null;
private String from = null;
private String to = null;
/**
* @return the folder
*/
public String getFolder() {
return folder;
}
/**
* @param folder the folder to set
*/
public void setFolder(String folder) {
this.folder = folder;
}
/**
* @return the from
*/
public String getFrom() {
return from;
}
/**
* @param from the from to set
*/
public void setFrom(String from) {
this.from = from;
}
/**
* @return the to
*/
public String getTo() {
return to;
}
/**
* @param to the to to set
*/
public void setTo(String to) {
this.to = to;
}
}
要转换响应,我通常会使用ObjectMapper,如下所示:
// Get the json response
String json = response.getJson();
logger.debug("json " + json);
if (json != null) {
// Convert the json string to Event object
Event[] event = objectMapper.readValue(json, GeneralEvent[].class);
....
问题是json是由不同的对象组成的。我确实考虑过一个通用事件数据,其中包含不同类型事件返回的所有可能属性,但这是一个黑客攻击,并且使用相同名称来表示不同对象的不同事件存在冲突。
有人能提出解决这个问题的方法吗?
答案 0 :(得分:0)
在你的情况下,我最近在循环中使用了JSONObject和JSONArray类,以构建组成我的JSON字符串的每个java对象。
答案 1 :(得分:0)
json中的动态键通常使用keySet()
处理不确定这是否符合您的期望,但这可能是一个可能的解决方案 -
protected Map<String, Object> data = null;
迭代输入的json对象inputJsonObj
-
Map<String, Object> dataMap = new HashMap<>();
JSONObject data = (JSONObject) inputJsonObj.get("data");
Set<String> keys = data.keySet();
for (String key : keys) {
if(data.get(key) instanceof String) {
dataMap.put(key, data.get(key));
} else if(data.get(key) instanceof JSONObject) {
// handle this by creating a new Map and store it in the original map.
Map<String, Object> summaryMap = new HashMap<>();
// Iterate over your summary and store it as key value pairs in summaryMap.
// You can have this functionality recursive if you are expecting multi-level json.
dataMap.put(key, summaryMap);
}
}