21

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 は緯度オブジェクトと経度オブジェクトであり、どちらも同一に定義されています。

private String b;
private String d;

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

助けを得るのに十分な情報を提供できたことを願っています。必要に応じて、より多くの情報やテスト プロジェクトを提供できれば幸いです。これをjunitテストとして実行しています。

ありがとう。

4

2 に答える 2

31
Gson gson = new Gson();
gson.fromJson(jsonStr,YourClass.class);

非常に簡単。

于 2015-12-18T06:57:40.650 に答える
23

エラーの理由は、最上位の 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;
}

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

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

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

gson.fromJson(json, BoxSearch.class);
于 2013-05-23T20:31:00.390 に答える