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
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() + "");
}
});
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.
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();
}
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;
}
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) {
}
});