7

JavaScript/RubyからJavaに来ています。動物用に次のJSONオブジェクトがあるとします。

{
  name: {
    common: "Tiger",
    latin: "Panthera tigris"
  }
  legs: 4
}

私はたくさんの動物APIを扱っていますが、それらすべてを次のような独自の共通形式に正規化したいと思います。

{
  common_name: "Tiger",
  latin_name: "Panthera tigris",
  limbs: {
    legs: 4,
    arms: 0
  }
}

たとえば、JavaScriptの場合、これは簡単です。

normalizeAnimal = function(original){
  return {
    common_name: original.name.common,
    latin_name: original.name.latin,
    limbs: {
      legs: original.legs || 0,
      arms: original.arms || 0
    }
  }
}

しかし、Javaではどうでしょうか。org.jsonのJSONObjectクラスを使用して、次のようなことを行うことができます。

public JSONObject normalizeAnimal(JSONObject original) throws JSONException{
  JSONObject name = original.getJSONObject("name");
  JSONObject limbs = new JSONObject();
  JSONObject normalized = new JSONObject();
  normalized.put("name_name", name.get("common"));
  normalized.put("latin_name", name.get("latin"));
  try{
    limbs.put("legs", original.get("legs");
  }catch(e){
    limbs.put("legs", 0);
  };
  try{
    limbs.put("arms", original.get("arms");
  }catch(e){
    limbs.put("arms", 0);
  };
  normalized.put("limbs", limbs);
  return normalized;
}

私が扱っているJSONオブジェクトが長くなり、深くなるにつれて、これはさらに悪化します。これらすべてに加えて、私は動物オブジェクトの多くのプロバイダーと取引しており、最終的には、変換を記述するための簡潔な構成形式(多分など"common_name": "name.common", "limbs.legs": "legs")を探しています。

Javaでこれを減らすにはどうすればよいですか?

4

4 に答える 4

7

Gson や Jackson などのライブラリを使用して、JSON を Java オブジェクトにマップします。

だから、あなたはのような豆を持つつもりです

public class JsonAnima {
    private JsonName name;
    private int legs; 
}
public class JsonName {
    private String commonName;
    private String latinName;
}

これは、(Jacksonを使用して)任意のライブラリで簡単に変換できます

ObjectMapper mapper = new ObjectMapper();
JsonAnimal animal = mapper.readValue(jsonString, JsonAnimal.class);

次に、「コンバーター」を作成して、JsonAnimal を Animal クラスにマップできます。

これはそれを行う方法です。: )


いくつかのリンク:

Gson: http://code.google.com/p/google-gson/

ジャクソン: http://wiki.fasterxml.com/JacksonHome

于 2012-09-28T19:16:02.473 に答える
1

純粋なJavaソリューションはすべて、ソースデータの信頼性の低い構造に対処するという課題に直面しています。JVMで実行している場合は、Groovyを使用してソースJSONの解析とビルドを行うことを検討することをお勧めします。結果は、上記で概説したJavascriptソリューションによく似たものになります。

import groovy.json.JsonBuilder
import groovy.json.JsonSlurper

def originals = [
  '{ "name": { "common": "Tiger", "latin": "Panthera tigris" }, "legs": 4 }',
  '{ "name": { "common": "Gecko", "latin": "Gek-onero" }, "legs": 4, "arms": 0 }',
  '{ "name": { "common": "Liger" }, "legs": 4, "wings": 2 }',
  '{ "name": { "common": "Human", "latin": "Homo Sapien" }, "legs": 2, "arms": 2 }'
]

originals.each { orig ->

  def slurper = new JsonSlurper()
  def parsed = slurper.parseText( orig )

  def builder = new JsonBuilder()
  // This builder looks a lot like the Javascript solution, no?
  builder { 
      common_name parsed.name.common
      latin_name parsed.name.latin
      limbs {
          legs parsed.legs ?: 0
          arms parsed.arms ?: 0
      }
  }

  def normalized = builder.toString()
  println "$normalized"
}

上記のスクリプトを実行すると、「ギザギザの」JSON(すべての要素が同じ属性を持つわけではありません)と次のような出力が処理されます...

{"common_name":"Tiger","latin_name":"Panthera tigris","limbs":{"legs":4,"arms":0}}
{"common_name":"Gecko","latin_name":"Gek-onero","limbs":{"legs":4,"arms":0}}
{"common_name":"Liger","latin_name":null,"limbs":{"legs":4,"arms":0}}
{"common_name":"Human","latin_name":"Homo Sapien","limbs":{"legs":2,"arms":2}}
于 2012-10-01T16:56:55.407 に答える
1

これをさまざまな種類のオブジェクトに使用する場合は、各オブジェクトを手動でシリアル化するのではなく、リフレクションを使用することをお勧めします。リフレクションを使用すると、normalizeAnimal のようなメソッドを作成する必要がなくなります。1 つのメソッドまたは 1 つのクラスを作成するだけで、json 形式へのシリアル化を行うことができます。

「mapping json java」を検索すると、役立つリファレンスがいくつか見つかります。グソンのように。これは彼らのウェブサイトにある例です:



    class BagOfPrimitives {
      private int value1 = 1;
      private String value2 = "abc";
      private transient int value3 = 3;
      BagOfPrimitives() {
        // no-args constructor
      }
    }

    //(Serialization)
    BagOfPrimitives obj = new BagOfPrimitives();
    Gson gson = new Gson();
    String json = gson.toJson(obj);  
    ///==> json is {"value1":1,"value2":"abc"}

    ///Note that you can not serialize objects with circular references since that will result in infinite recursion. 

    //(Deserialization)
    BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);   
    //==> obj2 is just like obj

于 2012-09-28T19:14:21.603 に答える