Retrofit 2: Get JSON from Response body

238,025

Solution 1

Use this link to convert your JSON into POJO with select options as selected in image below

enter image description here

You will get a POJO class for your response like this

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;
    }

}

and use interface like this:

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

and call like this:

Call<Result> call = api.checkLevel(1);
call.enqueue(new Callback<Result>() {
    @Override
    public void onResponse(Call<Result> call, Response<Result> response) { 
     if(response.isSuccessful()){
        response.body(); // have your all data
        int id =response.body().getId();
        String userName = response.body().getUsername();
        String level = response.body().getLevel();
        }else   Toast.makeText(context,response.errorBody().string(),Toast.LENGTH_SHORT).show(); // this will tell you why your api doesnt work most of time

    }

    @Override
    public void onFailure(Call<Result> call, Throwable t) {
     Toast.makeText(context,t.toString(),Toast.LENGTH_SHORT).show(); // ALL NETWORK ERROR HERE

    }
});

and use dependencies in Gradle

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

NOTE: The error occurs because you changed your JSON into POJO (by use of addConverterFactory(GsonConverterFactory.create()) in retrofit). If you want response in JSON then remove the addConverterFactory(GsonConverterFactory.create()) from Retrofit. If not then use the above solution

Solution 2

If you want to get whole response in JSON format, try this:

I have tried a new way to get whole response from server in JSON format without creating any model class. I am not using any model class to get data from server because I don't know what response I will get or it may change according to requirements.

this is JSON response:

{"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. In your API interface change the parameter

    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. in your main activity where you are calling this

    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. after that you can normally get parameter using JSON object and JSON array

Output enter image description here

Solution 3

use this to get String

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

instead of

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

and always keep a check for null before converting responsebody to string

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

Solution 4

You can use it like this.

 public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
            if (response.isSuccessful()) {
                try {
                    JSONObject jsonObject = new JSONObject(new Gson().toJson(response.body()));
                    msg = jsonObject.getString("msg");
                    status = jsonObject.getBoolean("status");

                    msg = jsonObject.getString("msg");
                    status = jsonObject.getBoolean("status");
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
                Log.e("cvbnop",response.body().toString());
            } else {
                Toast.makeText(MainActivity.this, "Some error occurred...", Toast.LENGTH_LONG).show();
            }
        }

Solution 5

I found that a combination of the other answers works:

interface ApiInterface {
    @GET("/someurl")
    Call<ResponseBody> getdata()
}

apiService.getdata().enqueue(object : Callback {
    override fun onResponse(call: Call, response: Response) {
        val rawJsonString = response.body()?.string()
    }
})

The important part are that the response type should be ResponseBody and use response.body()?.string() to get the raw string.

https://stackoverflow.com/a/33286112/860488

Share:
238,025
Dirus
Author by

Dirus

Updated on July 05, 2022

Comments

  • Dirus
    Dirus almost 2 years

    I want to get string json from my api using retrofit 2, I have no problem when using retrofit 1 to get this json but using retrofit 2 returns null for me.

    This is what my json looks like

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

    This is my API

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

    This is how my code looks like

    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) {
                }
            });
    

    I'm new to retrofit 2 and using above code, it always make my apps crash because response.body().toString() returns null.

    Please guide me on how to get that json string so I can convert it into JsonObject.

  • Samir
    Samir over 7 years
    Closest solution that I was looking for but new version is giing us public void onResponse(retrofit.Response<ReturnSignUp> response, Retrofit retrofit) but my models are like hastebin.com/cobezeyoyi.java and response.body(). not giving my get methods...
  • sushildlh
    sushildlh over 7 years
    for OP question the POJO is correct . If you have different question like this then you have to create getter and setter methods , which is not present in your POJO .
  • Kamil Nękanowicz
    Kamil Nękanowicz almost 7 years
    this does not work...the response body is a one-shot value that may be consumed only once So when in debug there is a call "behind the scene" from the inspector and the body is always empty.
  • Julio
    Julio almost 7 years
    I'm sorry to disagree, but Retrofit does not generate POJO from json, but only an object based on a previously declared POJO.
  • John O'Reilly
    John O'Reilly almost 7 years
    Yes, that was what I meant..."generate POJO instance" would I agree have been clearer
  • Ohad Kravchick
    Ohad Kravchick about 6 years
    response.body() already built a POJO for your retrofit call, which doesn't necessarily have a string() method.
  • Fran Marzoa
    Fran Marzoa about 5 years
    Just a note: you need to add the 'com.squareup.retrofit2:converter-gson:<version>' to your dependencies to use such converter.
  • Nancy
    Nancy about 4 years
    how would you create a POJO class that has json objects inside other json objects?
  • sushildlh
    sushildlh about 4 years
    As the above answer included the link of the website which gives you all POJO objects. You have to give that website JSON Object. As your comment, it is not too complex to create your solution. Share with me on my LinkedIn I will try to solve your problem.