web-dev-qa-db-fra.com

Chaîne JSON à Java utilisant GSON

J'essaie d'analyser json en Java.

J'ai la chaîne suivante qui est valide json selon jsonlint.com

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"
        +"          }"
        +"      }"
        +"  ]"
        +"]";

J'essaie de l'analyser en un objet et j'obtiens l'erreur suivante. "BEGIN_OBJECT attendu mais BEGIN_ARRAY à la ligne 1, colonne 2"

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

BoxSearch se compose de cela.

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

Boxes est un objet Latitude et un objet Longitude qui sont tous deux définis identiques.

private String b;
private String d;

Je peux analyser les attributs de niveau supérieur (lat1, lat2, long1 et long2) dans un objet BoxSearch plus simple qui n'a que ces 4 attributs. Le problème survient lorsque le json et l'objet sont plus complexes. Est-il même possible de faire ce que j'essaie?

J'espère avoir fourni suffisamment d'informations pour obtenir de l'aide. Je serais heureux de fournir plus d'informations ou même un projet de test si besoin est. Je lance cela comme un test junit.

Merci.

17
user2415153

La raison de l'erreur est que votre JSON au niveau supérieur est un tableau, pas un objet. Cela est couvert par GSON lançant "BEGIN_OBJECT attendu mais BEGIN_ARRAY"? .

Cependant, la solution ne fonctionnera pas pour votre JSON car vous avez un tableau de types mixtes (un objet et un tableau) plutôt qu'un tableau d'un seul type d'objet. Pour cela, vous devrez écrire un désérialiseur personnalisé (voir la section du guide de l'utilisateur de Gson qui couvre cela ) ou utiliser la classe JsonParser de Gson directement et extraire les données de l'arbre d'analyse.

Modifier à partir des commentaires ci-dessus:

Si vous êtes celui qui crée le JSON, il regarde comme ce que vous voulez est un tableau d'objets BoxSearch?

En fonction de votre classe Java BoxSearch, vous aurez besoin d'un JSON structuré comme:

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

Cependant, la façon dont vous avez défini la classe Boxes ne fonctionnera pas pour cela. (Vouliez-vous en avoir un ensemble?). En l'état, il devrait ressembler à ceci:

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

class Box {
   String b;
   String d;
}

Vous avez maintenant un tableau contenant un type d'objet (BoxSearch) que vous pouvez désérialiser avec:

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

Si vous n'avez vraiment pas besoin d'un tableau de ceux-ci, débarrassez-vous du tableau externe et faites simplement:

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

très facile.

28
王怡飞