okhttp 获取失败响应

Posted

技术标签:

【中文标题】okhttp 获取失败响应【英文标题】:okhttp get failure response 【发布时间】:2016-08-30 04:23:59 【问题描述】:

我已经在我的 android 客户端中为网络调用实现了 okhttp。

当我收到失败响应时,我会收到失败代码和与代码相关的文本作为消息,但我没有收到服务器发送给我的自定义失败响应。 在实现代码的失败响应中,我得到的消息只是“错误请求”。

而来自浏览器的相同响应如下。

我如何获得服务器返回给我的错误消息?

我的代码

private void executeCall(Request request, final ResponseListener listener) 
        mOKHttpClient.newCall(request)
                     .enqueue(new Callback() 
                         @Override
                         public void onFailure(Call call, IOException e)                               
                             postFailure(listener, (String) call.request()
                                                                .tag(),e.toString());
                         

                         @Override
                         public void onResponse(Call call, final Response response) throws IOException 
                             if(response.isSuccessful()) 
                                 String responseString = response.body().string();                                   
                                 postSuccess(listener, (String)call.request().tag(), responseString);
                             
                             else                                  
                                 postFailure(listener, (String)call.request().tag(),response.code()+","+response.message());
                             
                         
                     );
    

这是我在失败时的回应。

【问题讨论】:

当您的请求失败时,服务器可能会发送失败代码 400,因此它向您显示错误的请求,因此对于失败响应,您还需要设置状态 200 和消息,然后它才会接受响应从服务器 【参考方案1】:

您必须通过body() 捕获错误响应,因为response.message() 返回 HTTP 状态消息。

在您提供的屏幕截图中:

StatusOkHttp 中细分,例如response.code() 用于HTTP 状态代码,在您的情况下为400response.message() 用于HTTP 状态消息,在您的情况下为Bad Request .

响应的正文(无论是成功还是失败)是response.body()。如果您想以String 的形式获取它,请致电response.body().string()

@Override
public void onResponse(Call call, final Response response) throws IOException 
     if(response.isSuccessful()) 
         String responseString = response.body().string();                                   
         postSuccess(listener, (String)call.request().tag(), responseString);
     
     else                
        String errorBodyString = response.body().string();                  
        postFailure(listener, (String)call.request().tag(),response.code()+","+errorBodyString);
     

根据 cmets:

由于您想从响应中读取Message 对象,请尝试这样做:

JSONObject object = new JSONObject (response.body().string());
String messageString = object.getString("Message");

【讨论】:

response.body.string() 返回类似这样的 okhttp3.internal.http.RealResponseBody@528ae030 不,response.body 不会给你那个。它清楚地看起来它的内存参考。再次检查并尝试致电response.body().string() 我确实返回了相同的结果,我知道了原因。我必须以 json 对象的形式访问它,请参阅更新的代码 pastebin.com/Lp7eBnb2 这个 SO 帖子帮助我弄清楚 ***.com/a/36857049/3518278 更新了你的答案,我接受它。 好的,那么你想阅读Message 正文的对象吗?好吧,在这种情况下,是的,您必须将 String 响应转换为 JSON 对象才能读取。你正确地指出了它。 @ViVekH,检查更新的代码,应该可以工作。 :)【参考方案2】:

如果您尝试从改造响应中获取 (okhttp3.ResponseBody) errorResponse,请执行此操作..

                // Retrofit onResponseCall
                @Override
                public void onResponse(Call<MyResponse> call, Response<MyResponse> response) 

                    if (response.errorBody() != null) 

                        try 
                            Log.e("errorResponse","" + response.errorBody().toString());
                         catch (IOException e) 
                            e.printStackTrace();
                        
                     
                
                   

【讨论】:

我应该在哪里做这个?请详细说明你的答案。 如果您正在使用 Retrofit 调用 api 响应,那么这个重写方法 onResponseresponseCall.enqueue(Call call , Response response) 的一部分 我将 Retrofit 与 RxJava 一起使用,我显然没有在那里得到“调用”对象:/ 看看这个:Retrofit— A simple Android tutorial 我已经使用 robospice 和 okhttp。现在我已将 okhttp 迁移到 okhttp3。我应该为 RequestListener 和 spiceException 使用 okhttp3。

以上是关于okhttp 获取失败响应的主要内容,如果未能解决你的问题,请参考以下文章

okhttp 客户端何时缓存服务器响应?

如何缓存来自 Web 服务器的 okHTTP 响应?

OkHttp源码分析

OkHttp源码分析

OkHttp3 拦截器源码分析

使用OkHttp进行网络同步异步操作