2017-08-31 2 views
1

Je rencontre des difficultés pour obtenir une chaîne JSON et l'utiliser dans mon application Android. Donc, je cette classe Catégorie2, où je l'ai défini tous les champs une catégorie doit avoir:Android - Analyse JSON sans le nom du tableau à l'aide de Retrofit

public class Category2 { 

    @SerializedName("_id") 
    private String _id; 
    @SerializedName("name") 
    private String name; 
    @SerializedName("tasks") 
    private int tasks; 

    public Category2(String _id, String name, int tasks) { 

     this._id = _id; 
     this.name = name; 
     this.tasks = tasks; 
    } 


    public String get_id(){ 
     return _id; 
    } 
    public void set_id(String _id){ 
     this._id = _id; 
    } 
    public String getName(){ 
     return name; 
    } 
    public void setName(String name){ 
     this.name = name; 
    } 
    public int getTasks() { 
     return tasks; 
    } 
    public void setTasks(int tasks){ 
     this.tasks = tasks; 
    } 
} 

et moi avons une classe appelée CategoryResponse qui est essentiellement une liste de category2 que je reçois de la demande de mise à niveau:

public class CategoryResponse { 

    private List<Category2> results; 

    public List<Category2> getResults() { 
     return results; 
    } 

    public void setResults(List<Category2> results) { 
     this.results = results; 
    } 
} 

en général, je traite avec des chaînes JSON qui ont un nom pour les résultats même quand il est une liste d'éléments tels que:

{"genres":[{"id":28,"name":"Action"},{"id":12,"name":"Adventure"}]} 

lorsque la chaîne JSON est comme ci-dessus Je viens d'ajouter un sérialisé pour les résultats de la liste ci-dessus la déclaration de la liste:

@SerializedName("genres") 

Et il fonctionne très bien quand je déclare ma méthode GET:

@GET("/v3/projects/{projectId}/categories/") 
    Call<CategoryResponse> getProjectCategories(@Query("projectId") String projectId, @Header("Token") String token); 

Et je l'appelle dans mon activité:

categoryService = 
     CategoryClient.getClient().create(CategoryService.class); 

Call<CategoryResponse> call = categoryService.getProjectCategories(projectId,token); 
call.enqueue(new Callback<CategoryResponse>() { 
    @Override 
    public void onResponse(Call<CategoryResponse> call, Response<CategoryResponse> response) { 

     //int statusCode = response.code(); 
     listCategories = new ArrayList<>(); 
     listCategories = response.body().getResults(); 
     System.out.println("Size: " + response.body().getResults().size()); 
    } 

    @Override 
    public void onFailure(Call<CategoryResponse> call, Throwable t) { 
     // Log error here since request failed 
     Log.e(TAG, t.toString()); 
    } 
}); 

Mais ce que j'ai maintenant pour les catégories est quelque chose comme ceci:

[ 
    { 
     "_id": "59a6b18b2ba5c14bb76f28c8", 
     "createdAt": "2017-08-30T12:37:31.885Z", 
     "updatedAt": "2017-08-30T12:37:31.885Z", 
     "projectId": "598cbc74a1d0e57722ca98d1", 
     "companyId": "5602eb7ce49c9cd70409f206", 
     "name": "Arquitetura", 
     "__v": 0, 
     "tasks": 0 
    }, 
    { 
     "_id": "59a6b1be2ba5c14bb76f28c9", 
     "createdAt": "2017-08-30T12:38:22.407Z", 
     "updatedAt": "2017-08-30T12:38:22.407Z", 
     "projectId": "598cbc74a1d0e57722ca98d1", 
     "companyId": "5602eb7ce49c9cd70409f206", 
     "name": "Manutenção", 
     "__v": 0, 
     "tasks": 0 
    } 
] 

Donc, je ne peux pas sérialiser le nom de la liste des résultats et je reçois null quand j'appelle "response.body.GetResults()".

+0

Essayez de supprimer 'Category2' Copy Constructor. Si un constructeur de copie est disponible, aucun constructeur par défaut n'est appelé lorsque vous créez de nouveaux objets de classe 'Category2'. Essayez ceci et dites-moi si cela fonctionne –

Répondre

2

Sur votre code de service que renvoyer une Call<ArrayList<Category2>>

@GET("/v3/projects/{projectId}/categories/") 
Call<ArrayList<Category2>> getProjectCategories(@Path("projectId") String projectId, @Header("Token") String token); 

L'analyse sera correctement mise à niveau de cette façon.

EDIT

Comment vous appelez ce service:

categoryService = 
     CategoryClient.getClient().create(CategoryService.class); 

Call<ArrayList<Category2>> call = categoryService.getProjectCategories(projectId,token); 
call.enqueue(new Callback<ArrayList<Category2>>() { 
    @Override 
    public void onResponse(Call<ArrayList<Category2>> call, Response<ArrayList<Category2>> response) { 
     listCategories = response.body(); 
     System.out.println("Size: " + listCategories.size().toString()); 
    } 

    @Override 
    public void onFailure(Call<ArrayList<Category2>> call, Throwable t) { 
     // Log error here since request failed 
     Log.e(TAG, t.toString()); 
    } 
}); 
+0

Merci pour la réponse! J'essaye de faire les changements que vous avez suggérés mais j'obtiens toujours: essayez d'invoquer la méthode virtuelle 'int java.util.ArrayList.size()' sur une référence d'objet nulle. Et je sais que le résultat ne devrait pas revenir à zéro vu le jeton et le projetID que je suis en train de dépasser. –

+0

pourrait-il être en raison du service de rénovation? Vous devriez utiliser l'annotation '@Path (" projectId ")' au lieu de '@Query (" projectId ")' lorsque vous voulez ajouter le paramètre au chemin d'appel. –

+0

J'ai changé pour "@Path" mais je reçois la même erreur. Je suis en train de tester le lien en utilisant Postman et ça marche bien, en récupérant les résultats qu'il est censé faire. Mais dans Postman quand j'ajoute l'en-tête j'ajoute la clé qui est "Authorization" et la valeur, qui est le jeton. Dans l'application, je ne suis pas en ajoutant la clé. Pensez-vous que c'est à cause de ça? –

0

Ajouter les nouveaux champs à la classe Catégorie2 avec l'indication qu'ils sont transitoires, i.e., ils ne doivent pas être sérialisé. Gson: How to exclude specific fields from Serialization without annotations

public class Category2 { 

@SerializedName("_id") 
private String _id; 
@SerializedName("name") 
private String name; 
@SerializedName("tasks") 
private int tasks; 

private transient String createdAt, updatedAt, projectId, companyId; 
private transient int __v; 

public Category2(String _id, String name, int tasks) { 

    this._id = _id; 
    this.name = name; 
    this.tasks = tasks; 
} 


public String get_id(){ 
    return _id; 
} 
public void set_id(String _id){ 
    this._id = _id; 
} 
public String getName(){ 
    return name; 
} 
public void setName(String name){ 
    this.name = name; 
} 
public int getTasks() { 
    return tasks; 
} 
public void setTasks(int tasks){ 
    this.tasks = tasks; 
} 
} 

EDIT

Modifier cette

@GET("/v3/projects/{projectId}/categories/") 
Call<List<Category2>> getProjectCategories(@Path("projectId") String projectId, @Header("Authorization") String token); 

et ce

categoryService = 
    CategoryClient.getClient().create(CategoryService.class); 

Response<CategoryResponse> response = categoryService.getProjectCategories(projectId,token).execute(); 

//int statusCode = response.code(); 
listCategories = new ArrayList<>(); 
listCategories = response.body().getResults(); 
System.out.println("Size: " + response.body().getResults().size()); 
+0

Merci pour la réponse! J'ai fait ce que vous avez suggéré mais j'obtiens: Tentative d'invocation de la méthode virtuelle 'java.util.List com.construct.v2.models.category.CategoryResponse.getResults()' sur une référence d'objet null Mais je sais que pour le jeton et ProjectID Je passe je ne devrais pas obtenir une réponse nulle. –

+0

voir mon édition @MarcosGuimaraes – joao86