1
votes

Erreur RETROFIT attendue BEGIN_ARRAY mais BEGIN_OBJECT a été changé en objet fonctionne pour moi

Bonjour,

Je sais que cette question a été posée et que les deux autres sujets que j'ai trouvés m'ont aidé jusqu'à un certain point. J'ai une réponse du client sur laquelle je n'ai pas de contrôle, donc le format qu'il utilise est ce avec quoi je dois travailler.

Le Json contient une liste d'informations sur les utilisateurs de plusieurs utilisateurs. C'est la raison pour laquelle j'utilisais une liste au lieu d'un POJO. Le problème est le suivant. le POJO renvoie sans aucune erreur mais aussi sans aucune valeur et une seule valeur au lieu de plus d'une

Donc ce que je comprends, c'est que le JSON est dans un format où il n'est pas vu comme une liste mais comme objet.

Utilisation de POSTMAN comme outil de référence pour vérifier si l'appel GET fonctionne les valeurs retournées dans la liste

Je suis toujours un noob dans ce domaine donc toute aide sera appréciée.

La réponse JASON du facteur se présente comme suit (c'est là que j'ai réalisé que la façon dont sa récupération pouvait être vue comme un objet et non comme une liste.

Retrofit retrofit = new Retrofit.Builder().
  baseUrl("http://10..../com/").
  addConverterFactory(GsonConverterFactory.create()).
  build();

JasonPlaceHolder jasonPlaceHolderApi = retrofit.create(JasonPlaceHolder.class);

Call<UserInfo> call = jasonPlaceHolderApi.getUserInfo();
  call.enqueue(new Callback<UserInfo>() {
   @Override
    public void onResponse(Call<UserInfo> call, Response<UserInfo> response) {

     if(!response.isSuccessful()){
      textVierResults.setText("code: " + response.code());
     return;
  }
  UserInfo userInfos = response.body();

  //for(UserInfo ui:userInfos){
  String content = "";
  content += "Useremail: "    + userInfos.getUseremail()    + "\n";
  content += "Userpassword: " + userInfos.getUserpassword() + "\n";
  content += "Firstname: "    + userInfos.getFirstname()    + "\n";
  content += "Lastname: "     + userInfos.getLastname()     + "\n";
  content += "Userstatus: "   + userInfos.getUserstatus()   + "\n";

  textVierResults.append(content);

  // }


}



     @Override
      public void onFailure(Call<UserInfo> call, Throwable t) {
      Toast.makeText(MainActivity.this, "An error occurred", Toast.LENGTH_SHORT).show();
      textVierResults.setText(t.getMessage());
      }
      });

Il semble donc que je doive explorer un niveau supplémentaire pour accéder aux valeurs.

Encore quelques exemples

Ma classe d'interface:

public class UserInfo {

    private String userpassword;

    private String userstatus;

    private String useremail;

    private String firstname;

    private String lastname;


    public String getUserpassword() {
    return userpassword;
    }

    public String getUserstatus() {
    return userstatus;
    }

    public String getUseremail() {
    return useremail;
    }

    public String getFirstname() {
    return firstname;
    }

    public String getLastname() {
    return lastname;
    }
}


5 Réponses :


0
votes

Il semble donc que je doive explorer un autre niveau pour accéder aux valeurs.

Vous avez probablement raison, vous pourriez avoir besoin de quelque chose comme ça maintenant:

class SomeClass {

   ArrayList<UserInfo> info;
}

Et maintenant vous saisissez votre réponse dans ceci.


0 commentaires

0
votes

créer une nouvelle classe de modèle Les éléments passent le remplacer par UserInfo passé JasonPlaceHolder et classe Retrofit

public class Items{
List<UserInfo> items;

   public list<UserInfo> getitems() {
    return items;
    }

}





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

     if(!response.isSuccessful()){
      textVierResults.setText("code: " + response.getitems());
     return;
  }

2 commentaires

Dois-je encore exécuter les deux commandes "JasonPlaceHolder jasonPlaceHolderApi = retrofit.create (JasonPlaceHolder.class); Call > call = jasonPlaceHolderApi.getUserInfo ();" Pour démarrer la fonction "call.enqeue"


@GET ("allusers") Appeler getUserInfo (); "// Appeler getUserInfo (); WAS // remplacer ceci par l'ancien



0
votes

Si vous souhaitez analyser les données json manuellement pour accéder au nœud de liste dans l'arborescence json,

Ajoutez une classe JSONResponse qui représentera le JSON brut renvoyé et vous pourrez obtenir le tableau userInfos en utilisant la méthode getItems qui renvoie la valeur de la clé 'items' dans l'objet Json (dans ce cas, renvoie un tableau d'objets UserInfo)

JSONResponse jsonResponse = response.body();
userInfos= new ArrayList<>(Arrays.asList(jsonResponse.getItems()));
 String content = "";

for(UserInfo ui:userInfos){
content += "Useremail: "    + ui.getUseremail()    + "\n";
content += "Userpassword: " + ui.getUserpassword() + "\n";
content += "Firstname: "    + ui.getFirstname()    + "\n";
content += "Lastname: "     + ui.getLastname()     + "\n";
content += "Userstatus: "   + ui.getUserstatus()   + "\n";


}
textVierResults.append(content);

}

make La méthode Get renvoie un objet JSONResponse comme ci-dessous

@GET("allusers")
Call<JSONResponse> getUserInfo();"

Puis enfin, dans onResponse, récupère la liste des UserInfo à partir de l'objet JSONResponse comme ci-dessous

public class JSONResponse {
private UserInfo[] items;

public UserInfo[] getItems() {
    return items;
}


3 commentaires

Quel serait le type de "userInfos" dans la ligne "userInfos = new ArrayList <> (Arrays.asList (jsonResponse.getItems ()));"


ArrayList d'objets UserInfo tels que: ArrayList userInfos;


@RPN vérifie ma réponse mise à jour. La réponse mise à jour doit définir les informations pour tous les utilisateurs dans le textvierResults



0
votes

La première chose que votre réponse commence par {cela signifie que c'est un objet et que l'objet contient la liste son nom est items. Il y aura une classe principale racine qui contient la liste.

Alors créez la classe UserInfoRoot

  class UserInfoRoot {
@SerializedName("items")
@Expose
private List<UserInfo > userInfo = null;

public List<UserInfo > getUserInfo () {
    return userInfo ;
}

public void setUserInfo(List<UserInfo > userInfo ) {
   this.userInfo = userInfo ;
 }  
 }   

Maintenant, remplacez UserInfo par UserInfoRoot Appelez getUserInfo ();


2 commentaires

Existe-t-il une déclaration spécifique pour


Non, vous pouvez remplacer par votre classe, mais utilisez simplement @SerializedName ("items") . Remplacez par .



0
votes

essayez comme ci-dessous,

import retrofit2.Call;
import retrofit2.http.GET;

public interface JasonPlaceHolder {
    @GET("allusers")
    Call<responseUserInfor> getUserInfo();"
    //Call<List<UserInfo>> getUserInfo();  WAS
}

et créez un modèle de réponse incluant l'attribut du nom "items",

class responseUserInfor{
    private List<UserInfo> items;

    public List<UserInfo> getItems() {
        return items;
    }

    public void setItems(List<UserInfo> items) {
        this.items = items;
    }
}

et changez le lieu classe de détenteur comme ci-dessous.

public class UserInfo {

    private String userpassword;
    private String userstatus;
    private String useremail;
    private String firstname;
    private String lastname;


    public String getUserpassword() {
        return userpassword;
    }

    public String getUserstatus() {
        return userstatus;
    }

    public String getUseremail() {
        return useremail;
    }

    public String getFirstname() {
        return firstname;
    }

    public String getLastname() {
        return lastname;
    }
}


0 commentaires