web-dev-qa-db-fra.com

Retrofit 2: Obtenir JSON du corps de réponse

Je veux obtenir string json de mon api avec retrofit 2, je n’éprouve aucun problème à utiliser retrofit 1 pour obtenir ce json mais utiliser retrofit 2 renvoie null pour moi.

Voici à quoi ressemble mon Json

{"id":1,"Username":"admin","Level":"Administrator"}

Ceci est mon API

@FormUrlEncoded
@POST("/api/level")
Call<ResponseBody> checkLevel(@Field("id") int id);

Voici à quoi ressemble mon code

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Config.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        Api api = retrofit.create(Api.class);
        Call<ResponseBody> call = api.checkLevel(1);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                JsonObject post = new JsonObject().get(response.body().toString()).getAsJsonObject();
                    if (post.get("Level").getAsString().contains("Administrator")) {

                    }
            }

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

Je suis novice en rattrapage 2 et en utilisant le code ci-dessus, mes applications se bloquent toujours, car response.body().toString() renvoie null.

Veuillez me guider sur la façon d’obtenir cette chaîne JSON afin que je puisse la convertir en JsonObject.

32
Dirus

Utilisez ce link pour convertir votre JSON en POJO avec les options de sélection sélectionnées dans l'image ci-dessous

 enter image description here

Vous obtiendrez une classe POJO pour votre réponse comme ceci

public class Result {

    @SerializedName("id")
    @Expose
    private Integer id;
    @SerializedName("Username")
    @Expose
    private String username;
    @SerializedName("Level")
    @Expose
    private String level;

    /**
    * 
    * @return
    * The id
    */
    public Integer getId() {
        return id;
    }

    /**
    * 
    * @param id
    * The id
    */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
    * 
    * @return
    * The username
    */
    public String getUsername() {
        return username;
    }

    /**
    * 
    * @param username
    * The Username
    */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
    * 
    * @return
    * The level
    */
    public String getLevel() {
        return level;
    }

    /**
    * 
    * @param level
    * The Level
    */
    public void setLevel(String level) {
        this.level = level;
    }

}

et utilise l'interface comme ceci:

@FormUrlEncoded
@POST("/api/level")
Call<Result> checkLevel(@Field("id") int id);

et appelle comme ça:

Call<Result> call = api.checkLevel(1);
call.enqueue(new Callback<Result>() {
    @Override
    public void onResponse(Call<Result> call, Response<Result> response) {
        response.body(); // have your all data
        int id =response.body().getId();
        String userName = response.body().getUsername();
        String level = response.body().getLevel();
    }

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

et utiliser des dépendances dans gradale 

compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.+'

NOTE: L'erreur se produit parce que vous avez changé votre JSON en POJO (à l'aide de addConverterFactory(GsonConverterFactory.create()) en rattrapage). Si vous souhaitez une réponse en JSON, supprimez la addConverterFactory(GsonConverterFactory.create()) de Retrofit. Sinon, utilisez la solution ci-dessus

37
Sushil Kumar

Si vous voulez obtenir une réponse complète au format JSON, essayez ceci:

J'ai essayé une nouvelle façon d'obtenir une réponse complète du serveur au format JSON sans créer de classe de modèle. Je n'utilise aucune classe de modèle pour obtenir des données du serveur car je ne sais pas quelle réponse j'obtiendrai ou cela peut changer selon les besoins.

c'est la réponse JSON:

{"contacts": [
    {
        "id": "c200",
        "name": "sunil",
        "email": "[email protected]",
        "address": "xx-xx-xxxx,x - street, x - country",
        "gender" : "male",
        "phone": {
            "mobile": "+91 0000000000",
            "home": "00 000000",
            "office": "00 000000"
        }
    },
    {
        "id": "c201",
        "name": "Johnny Depp",
        "email": "[email protected]",
        "address": "xx-xx-xxxx,x - street, x - country",
        "gender" : "male",
        "phone": {
            "mobile": "+91 0000000000",
            "home": "00 000000",
            "office": "00 000000"
        }
    },
    .
    .
    .
]}
  1. Dans votre interface API, changez le paramètre

    public interface ApiInterface {
    @POST("/index.php/User/login")//your api link 
    @FormUrlEncoded
    Call<Object> getmovies(@Field("user_email_address") String title,
                    @Field("user_password") String body);
    }
    
  2. dans votre activité principale où vous appelez cette

    ApiInterface apiService =
            ApiClient.getClient().create(ApiInterface.class);
    
    Call call = apiService.getmovies("[email protected]","123456");
    call.enqueue(new Callback() {
        @Override
        public void onResponse(Call call, Response response) {
            Log.e("TAG", "response 33: "+new Gson().toJson(response.body()) );
        }
    
        @Override
        public void onFailure(Call call, Throwable t) {
            Log.e("TAG", "onFailure: "+t.toString() );
            // Log error here since request failed
        }
    });
    
  3. après cela, vous pouvez normalement obtenir un paramètre à l'aide d'un objet JSON et d'un tableau JSON

Sortie  enter image description here

26
Sunil

utilisez ceci pour obtenir String 

String res = response.body().string();

au lieu de

String res = response.body().toString();

et toujours garder une vérification de null avant de convertir responsebody en chaîne

if(response.body() != null){
     //do your stuff   
}

ajouter une dépendance pour retrofit2 

compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'

créer une classe pour l'URL de base

public class ApiClient     
{
public static final String BASE_URL = "base_url";

private static Retrofit retrofit = null;

public static Retrofit getClient() {
    if (retrofit==null) {
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
}

}

après que créer un modèle de classe pour obtenir de la valeur

public class ApprovalModel {

@SerializedName("key_parameter")
private String approvalName;
public String getApprovalName() {
    return approvalName;
}
}

créer une classe d'interface

public interface ApiInterface { 
@GET("append_url")
Call<CompanyDetailsResponse> getCompanyDetails();
}

après cela en classe principale

 if(Connectivity.isConnected(mContext)){
            final ProgressDialog mProgressDialog = new ProgressDialog(mContext);
            mProgressDialog.setIndeterminate(true);
            mProgressDialog.setMessage("Loading...");
            mProgressDialog.show();

            ApiInterface apiService =
                    ApiClient.getClient().create(ApiInterface.class);

            Call<CompanyDetailsResponse> call = apiService.getCompanyDetails();
            call.enqueue(new Callback<CompanyDetailsResponse>() {
                @Override
                public void onResponse(Call<CompanyDetailsResponse>call, Response<CompanyDetailsResponse> response) {
                    mProgressDialog.dismiss();
                    if(response!=null && response.isSuccessful()) {
                        List<CompanyDetails> companyList = response.body().getCompanyDetailsList();

                        if (companyList != null&&companyList.size()>0) {
                            for (int i = 0; i < companyList.size(); i++) {
                                Log.d(TAG, "" + companyList.get(i));
                            }
                         //get values
                        }else{
                            //show alert not get value
                        }
                    }else{
                        //show error message

                    }
                }

                @Override
                public void onFailure(Call<CompanyDetailsResponse>call, Throwable t) {
                    // Log error here since request failed
                    Log.e(TAG, t.toString());
                    mProgressDialog.dismiss();
                }
            });
        }else{
            //network error alert box

        }
2
Mahesh Pandit

Une meilleure approche consiste à laisser Retrofit générer un POJO pour vous à partir du JSON (en utilisant gson). La première chose à faire est d’ajouter .addConverterFactory(GsonConverterFactory.create()) lors de la création de votre instance Retrofit. Par exemple, si vous aviez une classe Java User (telle que celle illustrée ci-dessous) correspondant à votre json, votre API de conversion pourrait renvoyer Call<User>

class User {
    private String id;
    private String Username;
    private String Level;
    ...
}    
1
John O'Reilly

Donc, voici l'affaire:

En faisant 

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Config.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

Vous passez GsonConverterFactory.create () ici. Si vous le faites comme ceci, Gson convertira automatiquement l’objet json que vous obtenez en réponse à votre objet <ResponseBody>. Ici vous pouvez passer tous les autres convertisseurs tels que Jackson, etc ...

1
Vulovic Vukasin

Si vous n'avez pas idée de ce que pourrait être la réponse de l'API. Suivez les étapes pour convertir la valeur de réponse responsebody en octets et imprimer au format String. Vous pouvez obtenir la réponse complète imprimée dans la console. 

Ensuite, vous pouvez facilement convertir une chaîne en JSONObject.

      apiService.getFeeds(headerMap, map).enqueue(object : Callback, retrofit2.Callback<ResponseBody> {
            override fun onFailure(call: Call<ResponseBody>?, t: Throwable?) {
            }

            override fun onResponse(call: Call<ResponseBody>?, response: Response<ResponseBody>?) {
                val bytes = (response!!.body()!!.bytes())
                Log.d("Retrofit Success : ", ""+ String(bytes))
            }
        })
0
Sackurise