example ejemplo consumir body bad android retrofit

android - ejemplo - Retrofit 2.0-¿Cómo obtener el cuerpo de respuesta para 400 Error de solicitud incorrecta?



retrofit send json body (6)

Puedes probar el siguiente código para obtener 400 respuestas. Puede obtener una respuesta de error del método errorBody ().

Call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { //get success and error response here if (response.code() == 400) { if(!response.isSuccessful()) { JSONObject jsonObject = null; try { jsonObject = new JSONObject(response.errorBody().toString()); String userMessage = jsonObject.getString("userMessage"); String internalMessage = jsonObject.getString("internalMessage"); String errorCode = jsonObject.getString("errorCode"); } catch (JSONException e) { e.printStackTrace(); } } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { //get failure response here } } }

Entonces, cuando hago una llamada POST API a mi servidor, recibo un error 400 Bad Request con respuesta JSON.

{  "userMessage": "Blah", "internalMessage": "Bad Request blah blah", "errorCode": 1 }

Lo llamo por

Call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { //AA } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { //BB } }

Sin embargo, el problema es que una vez que obtengo la respuesta, onFailure () se invoca para que se llame a // BB. Aquí, no tengo forma de acceder a la respuesta JSON. Cuando registro la solicitud y respuesta de la API, no muestra ninguna respuesta JSON. Y Throwable t es IOException. Sin embargo, extrañamente, cuando hago la misma llamada en Postman, devuelve la respuesta JSON esperada con el código de error 400.

Entonces, mi pregunta es ¿cómo puedo obtener la respuesta json cuando obtengo el error 400 Bad Request? ¿Debo agregar algo a okhttpclient?

Gracias


Así es como puede manejar el mensaje de respuesta que estoy manejando para el error 500 que puede agregar tanto como desee.

switch (response.code()) { case HttpURLConnection.HTTP_OK: break; case HttpURLConnection.HTTP_UNAUTHORIZED: callback.onUnAuthentic(); break; case HttpURLConnection.HTTP_INTERNAL_ERROR: try { String errorResponse = response.errorBody().string(); JSONObject object = new JSONObject(errorResponse); String message = "Error"; if (object.has("Message")) message = String.valueOf(object.get("Message")); callback.onError(message); } catch (IOException e) { e.printStackTrace(); } break; case HttpURLConnection.HTTP_GATEWAY_TIMEOUT: case HttpURLConnection.HTTP_CLIENT_TIMEOUT: default: callback.onNetworkError(); break; }


Puede hacerlo como en su método onResponse , recuerde que 400 es un estado de respuesta, no un error:

if (response.code() == 400) { Log.v("Error code 400",response.errorBody().string()); }

Y puede manejar cualquier código de respuesta, excepto 200-300, con Gson como:

if (response.code() == 400) { Gson gson = new GsonBuilder().create(); ErrorPojoClass mError=new ErrorPojoClass(); try { mError= gson.fromJson(response.errorBody().string(),ErrorPojoClass .class); Toast.makeText(getApplicationContext(), mError.getErrorDescription(), Toast.LENGTH_LONG).show(); } catch (IOException e) { // handle failure to read error } }

Agrega esto a tu build.gradle : compile ''com.google.code.gson:gson:2.7''

Si desea crear una clase Pojo , vaya a Json Schema 2 Pojo y pegue su ejemplo de respuesta Json . Seleccione el tipo de fuente Json y la anotación Gson .


Tengo un problema similar, pero el código existente se adhiere a la cadena RxJava 2. Aquí está mi solución:

public static <T> Observable<T> rxified(final Call<T> request, final Class<T> klazz) { return Observable.create(new ObservableOnSubscribe<T>() { AtomicBoolean justDisposed = new AtomicBoolean(false); @Override public void subscribe(final ObservableEmitter<T> emitter) throws Exception { emitter.setDisposable(new Disposable() { @Override public void dispose() { request.cancel(); justDisposed.set(true); } @Override public boolean isDisposed() { return justDisposed.get(); } }); if (!emitter.isDisposed()) request.enqueue(new Callback<T>() { @Override public void onResponse(Call<T> call, retrofit2.Response<T> response) { if (!emitter.isDisposed()) { if (response.isSuccessful()) { emitter.onNext(response.body()); emitter.onComplete(); } else { Gson gson = new Gson(); try { T errorResponse = gson.fromJson(response.errorBody().string(), klazz); emitter.onNext(errorResponse); emitter.onComplete(); } catch (IOException e) { emitter.onError(e); } } } } @Override public void onFailure(Call<T> call, Throwable t) { if (!emitter.isDisposed()) emitter.onError(t); } }); } }); }

transformar las respuestas de 400 como en la cadena rx es bastante simple:

Call<Cat> request = catApi.getCat(); rxified(request, Cat.class).subscribe( (cat) -> println(cat) );


Primer paso:

Crea tu clase POJO para respuesta de error. En mi caso, ApiError.java

public class ApiError { @SerializedName("errorMessage") @Expose private String errorMessage; public String getErrorMessage() { return errorMessage; } public void setErrorMessage(String errorMessage) { this.errorMessage= errorMessage; } }

Segundo paso:

Escriba abajo el código en su devolución de llamada api.

Call.enqueue(new Callback<RegistrationResponse>() { @Override public void onResponse(Call<RegistrationResponse> call, Response<RegistrationResponse> response) { if (response.isSuccessful()) { // do your code here } else if (response.code() == 400) { Converter<ResponseBody, ApiError> converter = ApiClient.retrofit.responseBodyConverter(ApiError.class, new Annotation[0]); ApiError error; try { error = converter.convert(response.errorBody()); Log.e("error message", error.getErrorMessage()); Toast.makeText(context, error.getErrorMessage(), Toast.LENGTH_LONG).show(); } catch (IOException e) { e.printStackTrace(); } } } @Override public void onFailure(Call<RegistrationResponse> call, Throwable t) { //do your failure handling code here } }

Aquí ApiClient.retrofit es su instancia de ApiClient.retrofit que es estática.


public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { DialogHelper.dismiss(); if (response.isSuccessful()) { // Success } else { try { JSONObject jObjError = new JSONObject(response.errorBody().string()); Toast.makeText(getContext(), jObjError.getString("message"), Toast.LENGTH_LONG).show(); } catch (Exception e) { Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_LONG).show(); } } }