web-dev-qa-db-fra.com

Comment récupérer un tableau JSON et utiliser gson pour analyser chaque objet json? (Rénovation)

Je renvoie un tableau de résultats avec mes objets json, et j'essaie d'utiliser ma classe customObjectResponse pour extraire chacun des champs de chacun des objets ... le problème est qu'il attend un objet alors comment puis-je modifier ma classe pour lui permettre de rentrer un tableau d'objets pour pouvoir ensuite appeler les champs de chaque objet ... Je suis confus quant à ce qu'il faut ajouter:

Voici un exemple de réponse de ce qui est passé pour être utilisé:

[
  {
    itemId: 'dfsdfsdf343434',
    name: 'tests',
    picture: '6976-7jv8h5.jpg',
    description: 'testy.',
    dateUpdated: 1395101819,

  }
]

Voici ma classe d'objet de réponse:

public class ObjResponse{
    private String itemId;
    private String name;
    private String picture;

    private String description;

    private String location;
    private int dateUpdated;

    private String msg;




    //gridview constructor
    public ObjResponse(String picture) {
        this.picture = picture;
    }

    //public constructor
    public ObjResponse() {

    }

    public String getItemId() {
        return itemId;
    }

    public void setItemId(String itemId) {
        this.itemId = itemId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPicture() {
        return picture;
    }

    public void setPicture(String picture) {
        this.picture = picture;
    }


    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }


    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }



    public int getDateUpdated() {
        return dateUpdated;
    }

    public void setDateUpdated(int dateUpdated) {
        this.dateUpdated = dateUpdated;
    }




    public String getMsg() {
        return msg;
    }

}

ce que j'essaie, mais ne fonctionne pas, même si je sépare les classes dans leurs propres fichiers:

Data passed in:
items: [{obj1: "A", obj2: ["c", "d"]}, {etc...}]


public class Response {

        public class List<Custom> {
                private List<Custom> items;
        }

        public class Custom {
                private String obj1;
                private List<Obj2> obj2;
        }

        public Class Obj2 {
                private String letters;
        }
}
23
Lion789

J'ai fini par appeler dans le rappel une liste de customObject et il a fait le travail ...

new Callback<List<ObjResponse>>() {
34
Lion789

Au départ, j'ai eu du mal à me faire une idée de la façon dont le OP a résolu son problème, mais, après des jours de débogage, j'ai finalement compris comment résoudre ce problème.

Donc, vous avez essentiellement des données au format comme ceci (tableau JSON d'objets JSON):

[
    {
      ...
    }
] 

Votre classe qui modélise les données et contient les méthodes getter et setter n'est rien de plus que votre POJO typique.

public class Person implements Serializable {
    @SerializedName("Exact format of your json field name goes here")
    private String firstName;

    // Getters and Setters....
}

Dans votre interface contenant vos annotations RESTful à partir desquelles vous souhaitez convertir votre appel:

Avant:

public interface APInterface {
    @GET("SOME URL TO YOUR JSON ARRAY")
    Call<Person>(...)
}

Après:

public interface APInterface {
    @GET("SOME URL TO YOUR JSON ARRAY")
    Call<List<Person>>(...)
}

Dans votre activité Android, vous souhaitez convertir tous les appels sous la forme de Call<Person> à Call<List<Person>>

Enfin, lors de l'appel initial de la demande asynchrone, vous souhaiterez convertir vos rappels de cette manière.

call.enqueue(new Callback<List<Person>>() {
    @Override
    public void onResponse(Call<List<Person>> call, Response<List<Person>> response) {

        if(response.isSuccessful()){
            List<Person> person = response.body();

           // Can iterate through list and grab Getters from POJO
           for(Person p: person){...}


        } else {
            // Error response...
        }

    }

    @Override
    public void onFailure(Call<List<Person>> call, Throwable t) {...}
});

J'espère que cela aide les autres qui sont perdus de la réponse acceptée ci-dessus.

11
coletrain

Cela peut également fonctionner en passant simplement un tableau d'objets de réponse. Donc, si c'est votre objet de réponse:

public class CustomUserResponse {
    public String firstName;
    public String lastName;
    ...
}

Vous pouvez utiliser la syntaxe associée, selon la façon dont vous utilisez les rappels. Tel que:

new Callback<CustomUserResponse[]>(){
    @Override
    public void success(CustomUserResponse[] customUserResponses, Response rawResponse) {

    }

    @Override
    public void failure(RetrofitError error) {

    }
};

OR

public class GetUserCommand implements Callback<CustomUserResponse[]> { ...

En termes simples, à chaque endroit où vous remplacez normalement T par une classe de réponse, remplacez-le par un tableau, à la place comme dans CustomUserResponse[].


REMARQUE: pour éviter les erreurs confuses, assurez-vous également d'utiliser un tableau dans la définition d'interface Retrofit:

@POST ( "/users" )
public void listUsers(@Body GetUsersRequest request, Callback<CustomUserResponse[]> callback);
4
gMale

Vous pouvez essayer quelque chose comme ça

JSONObject jsonObject = new JSONObject(<your JSON string result>);
JSONArray jsonArray = jsonObject.getJSONArray();

//use GSON to parse
if (jsonArray != null) {
   Gson gson = new Gson();
   ObjResponse[] objResponse = gson.fromJson(jsonArray.toString(), ObjResponse[].class);
   List<ObjResponse> objResponseList = Arrays.asList(objResponse);
}

Cela devrait certainement fonctionner.

2
VikramV