使用Retrofit从RetrofitError对象获取JSON

neo*_*ion 39 android retrofit

我正在使用Retrofit库对我正在使用的服务进行REST调用.

如果我对我的服务进行API调用并出现故障,该服务会返回一些JSON以及标准的HTTP错误内容.使用RetrofitError故障回调中包含的对象,我能够找到HTTP状态代码和其他几个东西,但是我无法检索服务发回的JSON.

例如,假设我调用了我尝试创建用户的API.如果用户名已经存在,该服务将返回400错误代码以及一些JSON,如下所示:

{"error":"Username already in use"}
Run Code Online (Sandbox Code Playgroud)

因为一个简单的400错误代码不够具体,我真的需要访问返回的JSON.

有谁知道我如何获得这个JSON数据?我试着查看RetrofitError对象中的每个字段,但无法在任何地方找到它.我还需要做些什么吗?

Luk*_*iko 103

您可以使用该对象的getBodyAs方法RetrofitError.它将响应转换为Java对象,与其他Retrofit转换类似.首先定义一个描述JSON错误响应的类:

class RestError {
    @SerializedName("code")
    public int code;
    @SerializedName("error")
    public String errorDetails;
}
Run Code Online (Sandbox Code Playgroud)

然后使用前面提到的方法更详细地获取描述错误的对象.

catch(RetrofitError error) {
    if (error.getResponse() != null) {
        RestError body = (RestError) error.getBodyAs(RestError.class);
        log(body.errorDetails);
        switch (body.code) {
            case 101:
                ...
            case 102:
                ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Retrofit 2.0改变了错误响应转换器的方式.您需要使用responseBodyConverter方法获取正确的转换器,并使用它来转换响应的错误主体.除非处理异常,否则这将是:

Converter<ResponseBody, RestError> converter 
    = retrofit.responseBodyConverter(RestError.class, new Annotation[0]);
RestError errorResponse = converter.convert(response.errorBody());
Run Code Online (Sandbox Code Playgroud)


Cab*_*zas 20

试试这个代码

@Override
public void failure(RetrofitError error) {
    String json =  new String(((TypedByteArray)error.getResponse().getBody()).getBytes());
    Log.v("failure", json.toString());
}
Run Code Online (Sandbox Code Playgroud)

使用Retrofit 2.0

@Override
public void onFailure(Call<Example> call, Throwable t) {
    String message = t.getMessage();
    Log.d("failure", message);
}
Run Code Online (Sandbox Code Playgroud)

  • 这可以很好地检索HTTP响应体,但最好将它包装到try {} catch块中,因为它可能是getResponse()/ getBody为null的情况,并且此代码将抛出NullPointer异常,例如,非HTTP响应异常,例如:retrofit.RetrofitError:recvfrom failed:ECONNRESET(由对等方重置连接) (4认同)

ar-*_*r-g 5

@LukaCiko在改造1.6.1时回答我现在没有工作.就像我现在这样做:

    @Override
    public void failure(RetrofitError retrofitError) {
        String json =  new String(((TypedByteArray)retrofitError.getResponse().getBody()).getBytes());
        //own logic for example
        ExampleHandlerError error = new Gson().fromJson(json, ExampleHandlerError.class);
    }
Run Code Online (Sandbox Code Playgroud)


Jar*_*ard 5

两个getBodyAs用于获取JSON对象的Liner .

JsonObject responseAsJson = (JsonObject) retrofitError.getBodyAs(JsonElement.class);

String message = responseAsJson.get("error").getAsString(); //=> "Username already in use"
Run Code Online (Sandbox Code Playgroud)

确认在Retrofit 1.x中工作.不确定Retrofit 2.x需要进行哪些更改.