retrofit calling json data but its response show null - android

Here is my code any one help, why it shows response is null? There is some mistake which I cannot found.
public void getAllTasksWithSuccess(){
String url = ""+ RetrofitClient.baseURL +"here is my service code ";
RetrofitClient.createRetrofitInstance();
Call<ResponseBody> call = RetrofitClient.getCallObject("getTodaysTask",url);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.i("TAG",response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.i("tag2", "Failed : " + t.getMessage());
}
});
}
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String okhttp3.ResponseBody.string()' on a null object reference
at com.ra.ra.DashboardFragments.FragmentTasks$2.onResponse(FragmentTasks.java:83)

Add below class ServiceGenerator:
public class ServiceGenerator {
public static final String API_BASE_URL = AppConstants.BASE_URL;
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
public static Retrofit retrofit = null;
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
public static Retrofit retrofit() {
retrofit = builder.client(httpClient.build()).build();
return retrofit;
}
}
And use below ErrorUtils class to parse your response's errorBody:
public class ErrorUtils {
public static ResponseBody parseError(Response<?> response) {
Converter<ResponseBody, ResponseBody> converter =
ServiceGenerator.retrofit()
.responseBodyConverter(ResponseBody.class, new Annotation[0]);
ResponseBody error;
try {
error = converter.convert(response.errorBody());
} catch (IOException e) {
return new ResponseBody();
}
return error;
}
}
And now in your onResponse do as below:
public void getAllTasksWithSuccess(){
String url = ""+ RetrofitClient.baseURL +"here is my service code ";
RetrofitClient.createRetrofitInstance();
Call<ResponseBody> call = RetrofitClient.getCallObject("getTodaysTask",url);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccessful()){
// here your response.body() will not be null
}else{
// here your response.body() will be null
// and here you might get your response in response.errorBody();
ResponseBody res= ErrorUtils.parseError(response);
System.out.println("Response is:"+ res.toString());
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.i("tag2", "Failed : " + t.getMessage());
}
});
}

Related

Problem in getting values from Json response

I am hitting a URL with four parameters, If parameters not match I will get the Following response.
This is my JSON response:
{
"result": "0"
}
Now my question is. How do I get that result value from response?
Here's, my Retrofit instance
public class RetrofitClientInstance {
private static Retrofit retrofit;
private static final String BASE_URL = "https://URL/";
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
Retrofit Interface
public interface ApiInterface {
#GET("f/f/ff.php")
Call<Object> verifyUser (#QueryMap Map< String, String > params );
}
Code for getting the response
ApiInterface apiInterface = RetrofitClientInstance.getRetrofitInstance().create(ApiInterface.class);
Call<Object> call = apiInterface.verifyUser(params);
call.enqueue(new Callback<Object>() {
#Override
public void onResponse(Call<Object> call, Response<Object> response) {
Log.e("Code ", response.code() + "");
if (!response.isSuccessful()) {
Log.e("Code ", response.code() + "");
return;
}
// Convert String to json object
JSONObject json = null;
String str_value = null;
try {
json = new JSONObject(String.valueOf(response));
//JSONObject json_LL = json.getJSONObject("result");
// get value from LL Json Object
str_value = json.getString("result"); //<< get value here
} catch (JSONException e) {
e.printStackTrace();
}
// Log.e("Response ", json.length() + "");
Toast.makeText(RegistrationForm.this, str_value, Toast.LENGTH_SHORT).show();
Object responseBody = response.body();
}
#Override
public void onFailure(Call<Object> call, Throwable t) {
Log.e("Failed", t.getMessage() + "");
}
});
Since you're using Gson. You can replace Object with a class that holds the fields that you want to parse.
for example:
public class ResultResponse {
String result;
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
And change your endpoint method to return this class.
public interface ApiInterface {
#GET("f/f/ff.php")
Call< ResultResponse> verifyUser (#QueryMap Map< String, String > params );
}
Also don't forget to change the remaining code to use the new return type ResultResponse
Call<ResultResponse> call = apiInterface.verifyUser(params);
call.enqueue(new Callback<ResultResponse>() {
#Override
public void onResponse(Call<ResultResponse> call, Response<ResultResponse> response) {
Log.e("Code ", response.code() + "");
if (!response.isSuccessful()) {
Log.e("Code ", response.code() + "");
return;
}
ResultResponse resultResponse = response.body();
String str_value = resultResponse.getResult();
Toast.makeText(RegistrationForm.this, str_value, Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<Object> call, Throwable t) {
Log.e("Failed", t.getMessage() + "");
}
});

XML Parsing using Retrofit

I'm trying to make XML Response, but there is an exception.
Exception in onFailure:
org.simpleframework.xml.core.ElementException: Element 'Date' does not have a match in class
Client
public static Retrofit getXMLClient() {
if (retrofitXML == null) {
retrofitXML = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
}
return retrofitXML;
}
Interface
#GET("odds-" + oddsAccessMode + "1"+"?")
Call<PojoOddsResponse> getOddsData(#Query("api_key") String api_key);
API call
ApiInterfaceSR apiService =
ApiClientSR.getXMLClient().create(ApiInterfaceSR.class);
Call<PojoOddsResponse> call = apiService.getOddsData(API_KEY);
call.enqueue(new Callback<PojoOddsResponse>() {
#Override
public void onResponse(Call<PojoOddsResponse> call, Response<PojoOddsResponse> response) {
if (response.body() != null && response.code() == 200) {
try {
String s = response.body().toString();
Log.d(TAG, "onResponse: "+s);
} catch (Exception e) {
Log.e("JSON exception", e.getMessage());
}
}
}
#Override
public void onFailure(Call<PojoOddsResponse> call, Throwable t) {
Log.e("api exception", t.getMessage());
}
});
Help me, please.

Access sent parameter in onResponse of retrofit 2

I create a request with retrofit2 and send parameter to server, how can access sent parameter in onResponse?
retrofit = new Retrofit.Builder()
.baseUrl("baseAddress")
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiBase serviceSetParam = retrofit.create(ApiBase.class);
Call<String> myCall = serviceSetParam.setParam("data1","data2");
Callback<String> myCallback = new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
//i need access data1 & data2 Here !
if (response.isSuccessful()) {
String mResponse= response.body();
} else {
Utils.Log("unSuccessful");
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Utils.Log("onFailure");
}
};
myCall.enqueue(myCallback);
here the send param method:
#FormUrlEncoded
#POST("set")
Call<String> setParam(#Field("param1") String param1, #Field("param2") String param2);
in onResponse method of your request, test this code:
try {
BufferedSink bf = new Buffer();
call.request().body().writeTo(bf);
Log.i("params are",bf.buffer().readUtf8().toString());
} catch (IOException e) {
e.printStackTrace();
}
You need to get the original Request from OkHttp.
List<String> pathSegments = original(response.raw()).url().pathSegments();
given:
static Request original(Response response) {
while (true) {
Response prior = response.priorResponse();
if (prior == null) {
break;
}
response = prior;
}
return response.request();
}

Retrofit 2 - string error body is empty

Server returns JSON object in case of success and simple String for error case.
There are no problems with parsing JSON into object. The problem rises when I want to parse error since the response.errorBody().string() is empty.
When I send the same request using Postman the response as follows:
And I can't read this error... Anyone faced such problem?
Code code
gradle:
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile 'com.squareup.okhttp:okhttp:2.6.0'
RestClient.java:
private static GitApiInterface gitApiInterface;
...
public static GitApiInterface getClient() {
if (gitApiInterface == null) {
OkHttpClient okClient = new OkHttpClient();
okClient.interceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response;
}
});
Retrofit client = new Retrofit.Builder()
.baseUrl(URL_BASE)
.addConverterFactory(GsonConverterFactory.create())
.build();
gitApiInterface = client.create(GitApiInterface.class);
}
return gitApiInterface;
}
ApiInterface.java:
public interface ApiInterface {
#POST("/register/user/{email}/")
Call<User> postRegisterUser(#Path(value = "email", encoded = true) String email,
#Query("firstname") String firstName,
#Query("lastname") String lastName,
#Query("country") String country,
#Query("phone") String phone,
#Query("deviceid") String deviceId);
...
ServerRequests.java:
public void registerUser(#NonNull String email,
#NonNull String firstName,
#NonNull String lastName,
#NonNull String country,
#NonNull String phone,
#NonNull String deviceId,
#NonNull final RegisterUserCallback callback) {
showProgressBar();
RestClient.GitApiInterface service = RestClient.getClient();
Call<User> call = service.postRegisterUser(email, firstName, lastName, country, phone, deviceId);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
hideProgressBar();
User user = response.body(); //this works great
if (response.isSuccess()) {
Log.d(TAG, "REGISTER success: " + response.message());
callback.onRegisteredUser(user);
} else {
try {
Log.e(TAG, "REGISTER fail: " + response.errorBody().string()); //empty error body
callback.onRegisterFailed(response.errorBody().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<User> call, Throwable t) {
hideProgressBar();
callback.onRegisterFailed("error");
}
});
}
My answer is based on HttpLoggingInterceptor class.
I wrote getStatusError() method by given in parameter response.errorBody().
private StatusError getStatusError(ResponseBody responseBody) {
StatusError statusError = null;
if (responseBody != null) {
try {
BufferedSource source = responseBody.source();
if (source != null) {
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
Charset charset = UTF8;
MediaType contentType = responseBody.contentType();
if (contentType != null) {
charset = contentType.charset(UTF8);
}
String string = buffer.clone().readString(charset);
if (!TextUtils.isEmpty(string)) {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
statusError = gson.fromJson(string, StatusError.class);
}
}
} catch (Exception e) {
LogUtils.LOGW(TAG, "Impossible to get StatusError stream", e);
}
}
return statusError;
}
StatusError is a POJO class to map (JSON) elements:
public class StatusError {
#SerializedName("message")
public String message;
#SerializedName("errors")
public ArrayList<ErrorDetail> errors;
}

Retrofit POST raw string body

I am using Retrofit to send a POST request to a server. The body of the POST must be in the form jdata={"key1":"value1",...} along with a Content-Type header set to application/x-www-form-urlencoded. I found a similar question but the accepted answer is not working.
Here's what I tried -
My interface
public interface APIHandler {
#Headers("Content-Type: application/x-www-form-urlencoded")
#FormUrlEncoded
#POST(URL)
Call<ResponseBody> getdata(#Field("jdata") String jdata);
}
Call function
public void load() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("BASE_URL")
.addConverterFactory(GsonConverterFactory.create())
.build();
// prepare call in Retrofit 2.0
APIHandler iAPI = retrofit.create(APIHandler.class);
String requestBody = "{\"id\":\"value\",\"id1\":\"value2\"}"
Call<ResponseBody> call = iAPI.getData(requestBody);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> c, Response<ResponseBody> response) {
if (response.isSuccess()) {
ResponseBody result = response.body();
String gs = new Gson().toJson(result);
Log.d("MainActivity", "response = " + gs + " status: " + statusCode);
} else {
Log.w("myApp", "Failed");
}
}
#Override
public void onFailure(Call<ResponseBody> c, Throwable t) {
}
});
}
But I receive response = null and status = 200. What am I doing wrong? The expected response is only a string and not a JSON array.
I am leaving this here so that it helps someone.
The above code is correct. As I mentioned in the last line, a plain string response was expected. But since it is not a JSON response, the conversion probably did not work and the response was null. The only solution I could find was to directly convert the response to string -
try {
stresp = response.body().string()
Log.d("MainActivity", "response = " + stresp + " status: " + statusCode);
} catch (IOException e) {
//Handle exception
}
There might be a better way to handle this but that worked for me!
You can use like that. I have tested this and it working fine
public interface APIHandler {
#POST(URL)
Call<ResponseBody> getdata(#Body JsonObject body);
}
Request body:
JsonObject requestBody = new JsonObject();
requestBody.addProperty("id", "value1");
requestBody.addProperty("id1", "value2");
Prepare call in Retrofit 2.0
APIHandler iAPI = retrofit.create(APIHandler.class);
And Call function :
Call<ResponseBody> call = iAPI.getData(requestBody);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> c, Response<ResponseBody> response) {
if (response.isSuccess()) {
String result = response.body().string();
Log.d("MainActivity", "response = " + result);
} else {
Log.w("myApp", "Failed");
}
}
#Override
public void onFailure(Call<ResponseBody> c, Throwable t) {
}
});

Categories

Resources