I am using retrofit 2.
When i receive an unsuccessful response do i have to close manually
the erroBody();
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
// Success
} else {
response.errorBody().close(); ???????????????????
}
}
No. There's no need to call response.errorBody().close(), during an unsuccessful response. In the same way, there's no need to call response.raw().close(); during a successful response.
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(#NonNull Call<ResponseBody> call,
#NonNull Response<ResponseBody> response) {
if (response.isSuccessful()) {
// successful response from server: HTTP status code is between 200 and 300
// log user in, etc
} else {
// unsuccessful response from server: HTTP status code is not between 200 and 300
// show toast, call onBackPressed(), etc
}
}
#Override
public void onFailure(#NonNull Call<ResponseBody> call, #NonNull Throwable t) {
// network exception occurred while talking to the server
// or an unexpected exception occurred while creating the request or processing the response
// Log.d(...);
}
});
Related
I tried to post raw data to server using retrofit method, but I receive the failure response like resĀ fail: Response{protocol=http/1.1, code=500, message=Internal Server Error, url=http://192.168.1.9:8000/api/deviceinfo}
apiService = RetrofitSingleton.createService(ApiService.class);
spyApp = new SpyApp();
Call<ModelResponse> call = apiService.eventsUpdate(jsonObj);
call.enqueue(new Callback<ModelResponse>() {
#Override
public void onResponse(Call<ModelResponse> call, Response<ModelResponse> response) {
Log.e("response", new Gson().toJson(response.body())); //This shows null
if (response.isSuccessful()) {
String status = response.body().getData().getStatus();
} else {
Log.e("res fail", response.toString());
}
}
#Override
public void onFailure(Call<ModelResponse> call, Throwable t) {
Log.e("failure",t.getMessage());
}
});
I would like to handle my response from server , but I don't know how JSON (from server) its looks like. So I tried to display response as String , but I cant do it. Is it possible to display response as String? And then handle the response correctly. thanks
(Retrofit 1.9)
LoginService loginService = RetrofitClient.createService(LoginService.class);
loginService.searchOffer(getToken(), offerSearch, new Callback<String>() {
#Override
public void success(String offerSearchRequestResource, Response response) {
String responseFromSercer = response.getBody();
}
#Override
public void failure(RetrofitError error) {
}
});
change your response model to
JSONObject (from Gson)
then in your
public void success(...){response.body.toString();}
like this:
Call<JsonObject> call = YOUR_API_INTERFACE().YOUR_METHOD(YOUR_PARAMS);
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, #NonNull Response<JsonObject> response) {
if(response.isSuccessful()) {
String responseFromSercer = response.body.toString();
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
.....
}
});
If you are sure the request runs successfully and there is a response back...use
System.out.println(response.getBody());
i'd also suggest you add Logging Interceptors here so that you can get a detailed view of all your API calls
I want to get the session id from the login panel and I am using Retrofit to make the request.
But when looking for the headers in the response I did't find any cookie set
And here is the request code:
Retrofit retrofit = new Retrofit.Builder().baseUrl(getResources().getString(R.string.baseurl)).addConverterFactory(GsonConverterFactory.create(gson)).build();
API api = retrofit.create(API.class);
Call<ResponseBody> call = api.loginhtml(et_user.getText().toString(), et_pass.getText().toString());
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
String head = String.valueOf(response.headers());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
by using this code you can have the session
response.headers().get("Set-Cookie")
I want to implement a error handling mechanism using Retorfit 2.
The solutions that are available are using RetrofitError class which I can't find in the current repo.
If you are making synchronous request, you define your request method in the interface as Call<List<Car>>.
Once you execute the request you receive response and deserialized data wrapped in Response<T> as Response<List<Car>>. This wrapped gives you access to headers, http codes and raw response body.
You can access error body as:
Call<List<Car>> carsCall = carInterface.loadCars();
try {
Response<List<Car>> carsResponse = carsCall.execute();
} catch (IOException e) {
e.printStackTrace();
//network Exception is throw here
}
if(carsResponse != null && !carsResponse.isSuccess() && carsReponse.errorBody() != null){
// handle carsResponse.errorBody()
}
For async calls, you receive Throwable, if I/O exception is thrown during the network call:
Call<List<Car>> call = service.loadCars();
call.enqueue(new Callback<List<Car>>() {
#Override
public void onResponse(Response<List<Car>> response) {
// Get result from response.body(), headers, status codes, etc
}
#Override
public void onFailure(Throwable t) {
//handle error
}
});
Call<List<data>> call = MyService.loadData();
call.enqueue(new Callback<List<data>>() {
#Override
public void onResponse(Call<List<data>> call, Response<List<data>> response) {
if (response.isSuccessful()) {
//Response success. Handle data here
}
else{
//For getting error message
Log.d("Error message",response.message());
//For getting error code. Code is integer value like 200,404 etc
Log.d("Error code",String.valueOf(response.code()));
}
}
#Override
public void onFailure(Call<List<data>> call, Throwable t) {
if (t instanceof IOException){
//Add your code for displaying no network connection error
}
});
The simple method:
int code = response.raw().code();
String message = response.raw().message();
I am not able to get success response status code from response like 200,201.. etc. As we can easily get error codes from RetrofitError class like error.isNetworkError() and error.getResponse().getStatus(). Is there any workaround for getting status codes?
As per Retrofit 2.0.2, the call is now
#Override
public void onResponse(Call<YourModel> call, Response<YourModel> response) {
if (response.code() == 200) {
// Do awesome stuff
} else {
// Handle other response codes
}
}
Hope it helps someone :-)
EDIT: Many apps could also benefit from just checking for success (response code 200-300) in one clause, and then handling errors in other clauses, as 201 (Created) and 202 (Accepted) would probably lead to the same app logic as 200 in most cases.
#Override
public void onResponse(Call<YourModel> call, Response<YourModel> response) {
if (response.isSuccessful()) {
// Do awesome stuff
} else if (response.code() == 401) {
// Handle unauthorized
} else {
// Handle other responses
}
}
You can get the status code in success() just like you do it in failure()
#Override
public void success(Object object, Response response) {
response.getStatus() // returns status code integer
}
Since you have a Response object in success callback as response.getStatus()
EDIT
I assume you are using okhttp with retrofit.
okhttp has a powerful tool called Interceptor
You can catch the response before retrofits Callback and get status code from the response:
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor(){
#Override
public Response intercept(Chain chain) throws IOException{
Request request = chain.request();
Response response = chain.proceed(request);
response.code()//status code
return response;
});
// then add it to you Restclient like this:
restAdapter = new RestAdapter.Builder()
.setEndpoint(URL_SERVER_ROOT)
.setClient(new OkClient(client)) //plus your configurations
.build();
To learn more about interceptors visit here.
i achieved it by following codes:
public abstract class BaseCallBack<T> {
public abstract void onSuccess(Response<T> response);
public abstract void onFailure(Response<T> response);
}
public abstract class SuccessCallback<T> extends BaseCallBack<T> implements Callback<T>{
#Override
public void onResponse(Call<T> call, Response<T> response) {
if(response.code()>= 400 && response.code() < 599){
onFailure(response);
}
else {
onSuccess(response);
}
}
#Override
public void onFailure(Call<T> call, Throwable t){
}
#Override
public void onSuccess(Response<T> response) {
}
#Override
public void onFailure(Response<T> response) {
}
}
When the rest api returns 400 etc then the onFailure method will be call by default. If you wanna do something onsuccess:(when returns 200 etc)
ServiceConnector.api.getHomePage().enqueue(new SuccessCallback<Void>() {
#Override
public void onSuccess(Response<Void> response) {
super.onSuccess(response);
}
});
you should get exception code iin onError response
HttpException httpException =((HttpException) e).code();