2016-03-25 9 views
0

RESTful WebサービスからJSON応答を取得するモジュールで作業しています。レスポンスは以下のようなものです。1つのjsonオブジェクトを別のJSONオブジェクトにマッピングするための処理時間を改善する

[{ 
    "orderNumber": "test order", 
    "orderDate": "2016 - 01 - 25", 
    "Billing": { 
     "Name": "Ron", 
     "Address": { 
      "Address1": "", 
      "City": "" 
     } 
    }, 
    "Shipping": { 
     "Name": "Ron", 
     "Address": { 
      "Address1": "", 
      "City": "" 
     } 
    } 
}] 

これは完全な回答ではなく、問題を詳述するための重要な要素があるだけです。

私がする必要があるのは、このJSONレスポンスを、アプリケーションが理解して処理できる別のJSONに変換することです。たとえば以下のように言ってください。

{ 
"order_number": "test order", 
"order_date": "2016-01-25", 
"bill_to_name": "Ron", 
"bill_to_address": "", 
"bill_to_city": "", 
"ship_from_name": "Ron", 
"ship_from_Address": "", 
"ship_from_city": "" 
} 

私がしようとしたアイデアは、私はJACKSONを使用してハッシュマップに受信応答してJSONObjectを変換してから応答JSONから適切な値を自分のアプリケーションのJSONのプレースホルダを置き換えるためにStrSubstitutorを使用していた(私のアプリケーションの文字列プレースホルダは以下のとおりです)。上記の応答に示すように、MAPへ

{"order_number":"${orderNumber}","order_date":"${orderDate}","bill_to_name":"${Billing.name}","bill_to_address":"${Billing.Address}","bill_to_city":"${Billing.City}","ship_from_name":"${Shipping.Name}","ship_from_Address":"${Shipping.Address}","ship_from_city":"${Shipping.City}"} 

しかし、私が直面した問題は

  1. JSONということでしたが、ネストされたJSONOBJECTでは動作しませんでした。またBilling.Name/Shipping.Nameなどに置き換えて、私は私 は、HashMapのためにそれらを変換するだろうというとき、応答から出荷/請求JSONObjectsを抽出しても、彼らは私の名前、市を与えるだろう、 アドレス1と

  2. キーとしないBilling.Name、Billing.City等

そこで解決策として、私は、入力として応答JSONObject(srcObject)と自分のアプリケーションのJSONObject(destObject)かかり、コードの以下の部分を書いて実行しますレスポンスJSONの値を処理して、アプリケーションJSONに収めます。

public void mapJsonToJson(final JSONObject srcObject, final JSONObject destObject){ 
     for(String key : destObject.keys()){ 
      String srcKey = destObject.getString(key) 
      if(srcKey.indexOf(".") != -1){ 
       String[] jsonKeys = srcKey.split("\\.") 
       if(srcObject.has(jsonKeys[0])){ 
        JSONObject tempJson 
        for(int i=0;i<jsonKeys.length - 1;i++){ 
         if(i==0) { 
          tempJson = srcObject.getJSONObject(jsonKeys[i]) 
         } else{ 
          tempJson = tempJson.getJSONObject(jsonKeys[i]) 
         } 
        } 
        destObject.put(key, tempJson.getString(jsonKeys[jsonKeys.length - 1])) 
       } 
      }else if(srcObject.has(srcKey)){ 
       String value = srcObject.getString(srcKey) 
       destObject.put(key, value) 
      } 
     } 
    } 

このコードの問題は、処理に時間がかかることです。私はより少ない処理時間でこのロジックをより良い方法で実装できる方法があるのか​​知りたいのですか?

+0

あなたは再帰アルゴリズムを考えましたか?通常、ネストされたデータを処理する方が効率的です。 –

+0

現在のコードでどのように実装することができますか?今のところ、私は2つのケースを考えています。私が応答でチェックする必要があるキーは、orderNumberのような単純なキーか、またはjsonにネストされたBilling.Address1です。 – Raghav

答えて

1

2つのデータ型のPOJOを作成し、ジャクソンのマッパーを使用して最初のPOJOとしてRESTデータを逆シリアル化し、次にRESTサービスからPOJOを受け入れる2番目のPOJOにコピーコンストラクタを作成し、すべてのデータをそのフィールドにコピーします。その後、ジャクソンのマッパーを使用してデータをJSONにシリアル化することができます。

上記のコードでもパフォーマンスの問題が発生した場合にのみ、JsonParser/JsonGeneratorを使用してデータを直接ストリームするなど、より高速で難しいアルゴリズムを見ていきます。

+0

私がここで言及したケースは単なる1つですが、アイテム、注文、出荷、請求書などの独自の要求/応答フォーマットのような4〜5個のリクエストを含む多くのそのようなAPIとそれぞれ通信しています。それで、私がやりとりするリクエストごとにPOJOを作成するのが実現可能な方法です。この場合、JSONObjectを直接扱うのはずっと簡単ですか? – Raghav

+0

コード保守性の観点と検証の観点からは、実際はありません。 POJOは自己文書化し、保守しやすく、デバッグしやすくなり、無償で検証します。直接解析/生成にはそれを与えるためにいくつかの重大なパフォーマンス改善が必要であり、テラバイトとテラバイトのデータを処理している場合を除いて、それらを見ることはできません。 –

0

私はJSONに相当するXSLTを使用するのが標準的なアプローチだと感じています。 JOLTはこのような実装の1つと思われます。デモページはhereです。それを見てみましょう。

関連する問題