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.
use this
response.body().get(0).getUsername().toString();
add dependency for 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'
create class for base url
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;
}
}
after that create class model to get value
public class ApprovalModel {
@SerializedName("key_parameter")
private String approvalName;
public String getApprovalName() {
return approvalName;
}
}
create interface class
public interface ApiInterface {
@GET("append_url")
Call<CompanyDetailsResponse> getCompanyDetails();
}
after that in main class
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
}
you can change your interface with code given below, if you need json String response..
@FormUrlEncoded
@POST("/api/level")
Call<JsonObject> checkLevel(@Field("id") int id);
and retrofit function with this
Call<JsonObject> call = api.checkLevel(1);
call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
Log.d("res", response.body().toString());
}
@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.d("error",t.getMessage());
}
});
If you don't have idea about What could be the response from the API. Follow the steps to convert the responsebody response value into bytes and print in the String format You can get the entire response printed in the console.
Then you can convert string to JSONObject easily.
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))
}
})
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
}
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.
try {
JSONObject jsonObject = new JSONObject(response.body().string());
System.out.println(jsonObject);
} catch (JSONException | IOException e ) {
e.printStackTrace();
}
A better approach is to let Retrofit generate POJO for you from the json (using gson
). First thing is to add .addConverterFactory(GsonConverterFactory.create())
when creating your Retrofit
instance. For example, if you had a User
java class (such as shown below) that corresponded to your json, then your retrofit api could return Call<User>
class User {
private String id;
private String Username;
private String Level;
...
}
So, here is the deal:
When making
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Config.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
You are passing GsonConverterFactory.create() here. If you do it like this, Gson will automatically convert the json object you get in response to your object <ResponseBody>
. Here you can pass all other converters such as Jackson, etc...
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();
}
}
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"
}
},
.
.
.
]}
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);
}
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
}
});
after that you can normally get parameter using JSON object and JSON array
Source: Stackoverflow.com