web-dev-qa-db-ja.com

JSON文字列をJava GSONを使用したオブジェクトに

私はjsonをJavaに解析しようとしています。

Jsonlint.comによると、次の文字列が有効なjsonです

private final static String LOC_JSON = 
         "["
        +"{"
        +"  \"lat1\": 39.737567,"
        +"  \"lat2\": 32.7801399,"
        +"  \"long1\": -104.98471790000002,"
        +"  \"long2\": -96.80045109999998"
        +"},"
        +"  ["
        +"      {"
        +"          \"lat\": {"
        +"              \"b\": 38.88368709500021,"
        +"              \"d\": 40.620468491667026"
        +"          },"
        +"          \"long\": {"
        +"          \"b\": -105.75306170749764,"
        +"          \"d\": -104.675854661387"
        +"          }"
        +"      }"
        +"  ]"
        +"]";

オブジェクトに解析しようとすると、次のエラーが発生します。 「BEGIN_OBJECTが必要ですが、1行2列目がBEGIN_ARRAYでした」

            Gson gson = new Gson();
        BoxSearch b = gson.fromJson( LOC_JSON, BoxSearch.class ); 

BoxSearchはこれで構成されています。

private Number lat1;
private Number lat2;
private Number long1;
private Number long2;
private Boxes[] boxes;

BoxesはLatitudeオブジェクトとLongitudeオブジェクトで、どちらも同じように定義されています。

private String b;
private String d;

上位レベルの属性(lat1、lat2、long1およびlong2)を解析して、これら4つの属性のみを持つより単純なBoxSearchオブジェクトにできます。問題は、jsonとオブジェクトがより複雑な場合に発生します。私がやろうとしていることをすることさえ可能ですか?

私はいくつかの助けを得るために十分な情報を提供したことを願っています。必要に応じて、さらに情報を提供したり、テストプロジェクトを提供したりできます。これをjunitテストとして実行しています。

ありがとう。

17
user2415153

エラーの理由は、最上位のJSONがオブジェクトではなく配列であるためです。これは、 GSONが「BEGIN_OBJECTが必要でしたがBEGIN_ARRAYでした」をスローすることでカバーされますか?

ただし、単一のタイプのオブジェクトの配列ではなく、混合タイプの配列(オブジェクトと配列)があるため、JSONに対するソリューションは機能しません。そのためには、カスタムデシリアライザを作成する必要があります( Gsonユーザーガイドのこのセクションをカバーするセクションを参照してください )またはGsonの JsonParser クラスを直接使用して、解析ツリーからデータを抽出します。

上記のコメントから編集:

あなたがJSONを作成しているのであれば、それはあなたが望むものはBoxSearchオブジェクトの配列のように見えます

Java BoxSearchクラスに基づいて、次のような構造のJSONが必要になります。

[
    {
        "lat1" : 39.737567,
        "lat2" : 32.7801399,
        "long1" : -104.98471790000002,
        "long2" : -96.80045109999998,
        "boxes" : [ 
                    {
                      "lat": {
                          "b": 38.88368709500021,
                          "d": 40.620468491667026
                      },
                      "long": {
                          "b": -105.75306170749764,
                          "d": -104.675854661387
                      }
                    }
                  ]
    }
]

ただし、Boxesクラスを定義する方法は、そのためには機能しません。 (あなたはそれらの配列を持つつもりでしたか?)現状のままである必要があります:

class Boxes {
    Box lat;
    @SerializedName("long")
    Box lon;
}

class Box {
   String b;
   String d;
}

これで、1つのタイプのオブジェクト(BoxSearch)を含む配列ができました。

Type collectionType = new TypeToken<Collection<BoxSearch>>(){}.getType();
Collection<BoxSearch> boxSearchCollection = gson.fromJson(json, collectionType);

これらの配列が本当に必要ない場合は、外側の配列を削除して、次のようにします。

gson.fromJson(json, BoxSearch.class);
21
Brian Roach
Gson gson = new Gson();
gson.fromJson(jsonStr,YourClass.class);

非常に簡単。

28
王怡飞