Retrofit 2.0 - 如何获得400 Bad Request错误的响应正文?

use*_*024 26 android retrofit

因此,当我对我的服务器进行POST API调用时,我收到了一个带有JSON响应的400 Bad Request错误.

{
   ?"userMessage": "Blah",
    "internalMessage": "Bad Request blah blah",
    "errorCode": 1
}
Run Code Online (Sandbox Code Playgroud)

我叫它

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
    }
}
Run Code Online (Sandbox Code Playgroud)

然而问题是,一旦我得到响应,就会调用onFailure()以便//调用BB.在这里,我无法访问JSON响应.当我记录api请求和响应时,它根本不显示JSON响应.并且Throwable t是IOException.然而,奇怪的是,当我在Postman上进行相同的调用时,它确实返回了400错误代码的预期JSON响应.

所以我的问题是当我收到400 Bad Request错误时如何获得json响应?我应该向okhttpclient添加一些东西吗?

谢谢

Yas*_*maz 40

你可以像在你的onResponse方法中那样做,记住400是响应状态而不是错误:

if (response.code() == 400) {              
    Log.v("Error code 400",response.errorBody().string());
}
Run Code Online (Sandbox Code Playgroud)

并且您可以处理除200-300之外的任何响应代码,Gson例如:

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
        }        
}
Run Code Online (Sandbox Code Playgroud)

将此添加到您的build.gradle:compile 'com.google.code.gson:gson:2.7'

如果你想创建Pojo类,请转到Json Schema 2 Pojo并粘贴你的示例Json响应.选择源类型Json和注释Gson.

  • @YasinKaçmaz你是对的,我的坏.RC 400在Retrofit 1.x中出现错误 (2认同)

Sat*_* VG 15

您可以尝试以下代码来获得400响应.您可以从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().string());
                        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
    }
}
}
Run Code Online (Sandbox Code Playgroud)

编辑:从固定方法名toStringstring


小智 13

使用您的类对象处理ErrorResponse

科特林

val errorResponse = Gson().fromJson(response.errorBody()!!.charStream(), ErrorResponse::class.java)
Run Code Online (Sandbox Code Playgroud)

爪哇

ErrorResponse errorResponse = new Gson().fromJson(response.errorBody.charStream(),ErrorResponse.class)
Run Code Online (Sandbox Code Playgroud)


Kes*_*era 8

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ekt*_*sar 5

第一步:

创建用于错误响应的 POJO 类。就我而言,ApiError.java

public class ApiError {

    @SerializedName("errorMessage")
    @Expose
    private String errorMessage;

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage= errorMessage;
    }
}
Run Code Online (Sandbox Code Playgroud)

第二步:

在您的 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
     }
}
Run Code Online (Sandbox Code Playgroud)

ApiClient.retrofit是您的静态改造实例。


小智 5

这是最简单的解决方案,

如果你想处理 onFailure 方法的响应:

@Override
public void onFailure(Call<T> call, Throwable t) {
    HttpException httpException = (HttpException) t;
    String errorBody = httpException.response().errorBody().string();
    // use Gson to parse json to your Error handling model class
    ErrorResponse errorResponse = Gson().fromJson(errorBody, ErrorResponse.class);
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您将 rxjava Observable 与 Kotlin 一起使用,请从错误正文中处理它:

{ error ->
    val httpException :HttpException = error as HttpException
    val errorBody: String = httpException.response().errorBody()!!.string()
    // use Gson to parse json to your Error handling model class
    val errorResponse: ErrorResponse = 
       Gson().fromJson(errorBody, ErrorResponse::class.java)
}
Run Code Online (Sandbox Code Playgroud)

不要忘记正确处理 json 到类的转换(如果不确定,请使用 try-catch)。