根据Json String类型将Json String转换为Object

时间:2017-11-28 13:51:15

标签: java json jackson

我有一个第三方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是由不同的对象组成的。我确实考虑过一个通用事件数据,其中包含不同类型事件返回的所有可能属性,但这是一个黑客攻击,并且使用相同名称来表示不同对象的不同事件存在冲突。

有人能提出解决这个问题的方法吗?

2 个答案:

答案 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);
     }
 }