【问题标题】:Retrofit connection failure returns RetrofitError.response as null改造连接失败将 RetrofitError.response 返回为 null
【发布时间】:2014-08-13 23:57:46
【问题描述】:

使用 Retrofit 1.6.0、OkHTTP 2.0.0 和 OkHTTP-UrlConnection 2.0.0。

我正在使用 Retrofit 对不存在的 URL 进行 POST 到服务。正如预期的那样,调用失败回调。但是,RetrofitError 参数没有响应。我真的很想获取使用返回的 HTTP 状态代码

error.getResponse().getStatus()

但由于 getResponse() 返回 null,我不能。

为什么 getResponse() 为空,如何获取状态?

谢谢。

此外,正如预期的那样,我收到的错误是 UnknownHostException。重复:我期待这个错误。我想知道如何获取 HTTP 状态码或者为什么 error.getResponse() 返回 null。

编辑:这是一些代码:

RestAdapterBuilderClass.java
    RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint("http://badURL.DoesntMatter/");
            .setRequestInterceptor(sRequestInterceptor)
            .setLogLevel(RestAdapter.LogLevel.FULL)
             .build();
    sService = restAdapter.create(ServiceInterface.class);

ServiceInterface.java
    @POST("/Login")
    void login(@Body JsonObject body, Callback<String> callback);

CallbackClass.java
    @Override
    public void failure(RetrofitError error) {
        if (error.getResponse() == null) {

            // error.getResponse() is null when I need to get the status code
            // from it.

            return;
        }
    }

【问题讨论】:

  • 你能粘贴你的代码示例吗
  • @NickCardoso 添加了失败回调的代码。
  • 谢谢,您能否包含整个代码示例(包括您发送请求和 URL 的部分) - 另外,错误是什么,不同的错误会为您提供不同的结果。当您可以搜索确切的错误时,Retfrofit 文档可能会非常好
  • @NickCardoso 还有一些从构建器到失败回调的代码。
  • 如果你无法连接到你请求的远程主机,你怎么能收到他的HTTP状态?

标签: java android retrofit okhttp


【解决方案1】:

当您收到 UnknownHostException 时,这意味着您无法建立与服务器的连接。事实上,在这种情况下,您不能期望 HTTP 状态。

当你可以连接到服务器时,你自然只会得到一个 Http 响应(以及一个状态)。

即使您收到 404 状态代码,您也已建立了与服务器的连接。这与 UnknownHostException 不同。

如果您没有收到响应,getResponse() 可以返回 null。

【讨论】:

  • 我想我只是假设我会得到一些东西。感谢您提出这个问题并且我提出这个问题。我将把它标记为已回答。
【解决方案2】:

RetrofitError 有一个名为isNetworkError() 的方法,您可以使用它来检测由于网络问题导致的失败请求。我通常会添加一个像这样的小辅助方法:

public int getStatusCode(RetrofitError error) {
    if (error.isNetworkError()) {
        return 503; // Use another code if you'd prefer
    }

    return error.getResponse().getStatus();
}

然后使用该结果来处理任何其他故障逻辑(在 401 上注销,在 500 上显示错误消息等)。

【讨论】:

  • 似乎被贬低了
  • 更新版本为public int getStatusCode(RetrofitError error) { if (error.getKind() == RetrofitError.Kind.NETWORK) { return 503; // Use another code if you'd prefer } return error.getResponse().getStatus(); }
【解决方案3】:

只是为了扩展@lyio 的答案,我从 Fabric 日志记录中发现 getKind() 有时会返回 UNEXPECTED,然后如果您解析消息,您会遇到超时和连接问题,因此我在下面编写了实用程序类。

public class NetworkUtils {
    // Compiled from Fabric events
    private static final List<String> networkErrorStrings = new ArrayList<>(Arrays.asList(
        "Unable to resolve host",
        "Connection closed by peer",
        "Failed to connect",
        "timeout",
        "Connection timed out"));

    public static boolean isNetworkError(@Nullable RetrofitError retrofitError) {
        if (retrofitError != null) {
            if (retrofitError.getKind() != RetrofitError.Kind.NETWORK) {
                for (String error : networkErrorStrings) {
                    if (retrofitError.getMessage().contains(error)) {
                        return true;
                    }
                }
            } else {
                return true;
            }
        }

        return false;
}

}

【讨论】:

  • 我遇到了同样的问题
【解决方案4】:

我正在使用 Retrofit 2。当端点 url 以“/”结尾时,如您的情况一样,并且在您的界面中再次以“/”开头 [@POST("/Login")] 会导致此问题。从 .setEndpoint() 方法中删除“/”

【讨论】:

    猜你喜欢
    • 2018-01-22
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    相关资源
    最近更新 更多