2017-11-28 14 views
0

私は、さまざまなイベントオブジェクトの配列であるjsonデータを返すサードパーティのAPI呼び出しを持ち、このデータを適切なオブジェクトに変換する方法がわかりません。Json StringをObjectに基づいてオブジェクトに変換するString型

[{ 
    "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 
     } 
    } 
} ... ] 

各イベントの「データ」属性が異なる属性が含まれています。次のように

JSON応答のサンプルです。イベント属性 'type'は、イベントの種類とそのデータ属性を定義します。共有属性を格納する抽象イベントクラスを作成しました。次のようにイベントの例は、 'のstateChanged'

@JsonIgnoreProperties(ignoreUnknown = true) 
public interface EventData { 

} 

されています:

@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 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

おそらく、データをマップとして保持する必要があります。 'keySet()'からデータのキーを取得し、それに応じて値をマッピングします。 – ajc

答えて

0

あなたのケースでは、最近JSONObjectとJSONArrayクラスをループ内で使用して、JSON Stringを構成する各Javaオブジェクトを構築しました。 JSONで

0

ダイナミックキーは、通常、これはあなたの期待に合う場合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); 
    } 
} 
関連する問題