5

我正在使用最新的 Volley 库,当我的 api 返回 204 且响应中没有正文时,我遇到了问题。BasicNetwork.java 中的以下代码似乎没有按预期工作:

// Some responses such as 204s do not have content.  We must check.
if (httpResponse.getEntity() != null) {
    responseContents = entityToBytes(httpResponse.getEntity());
} else {
    // Add 0 byte response as a way of honestly representing a
    // no-content request.
    responseContents = new byte[0];
}

getEntity 的结果对我来说永远不会为空,但它是空的。我通过检查 curl 和 postman 确保我的 API 没有返回任何内容(只是为了确保我不会发疯)。有没有其他人有这样的问题?

现在,我刚刚将其更改为:

if (statusCode != HttpStatus.SC_NO_CONTENT && httpResponse.getEntity() != null)

我知道这并不能解决根本原因,但我想确保在深入研究这个问题之前我没有遗漏任何明显的东西。

谢谢!

编辑:对不起,我忘了提到实际的问题是在方法 entityToBytes 中发生超时异常,这很奇怪,因为没有要检索的主体。

此外,我没有使用实际功能齐全的 Web 服务 API,因为它尚不可用。相反,我正在连接到 apiary 上的模拟 Web 服务,但我不知道 apiary 可能是问题所在。

4

2 回答 2

7

这与其说是一个答案,不如说是对您的解决方案的详细说明!首先,我使用来自我的 API 的 204 响应,并且遇到了与您完全相同的问题。我在 BasicNetwork.java 中使用了您的代码来解决它 - 行if (statusCode != HttpStatus.SC_NO_CONTENT && httpResponse.getEntity() != null)

我还发现,如果我使用标准JsonObjectRequest请求,Response.ErrorListener则会因为正文为空而触发。

我创建了一个新的JsonObjectRequestWithNull,它在空或空白正文的情况下提供成功响应。代码:

public class JsonObjectRequestWithNull extends JsonRequest<JSONObject> {

public JsonObjectRequestWithNull(int method, String url, JSONObject jsonRequest,
                         Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
    super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
            errorListener);
}

public JsonObjectRequestWithNull(String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener,
                         Response.ErrorListener errorListener) {
    this(jsonRequest == null ? Request.Method.GET : Request.Method.POST, url, jsonRequest,
            listener, errorListener);
}

@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
    try {
        String jsonString = new String(response.data,
                HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
        //Allow null
        if (jsonString == null || jsonString.length() == 0) {
            return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
        }
        return Response.success(new JSONObject(jsonString),
                HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
        return Response.error(new ParseError(e));
    } catch (JSONException je) {
        return Response.error(new ParseError(je));
    }
}

}

相关位是:

        //Allow null
        if (jsonString == null || jsonString.length() == 0) {
            return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
        }

希望对某人有所帮助。

于 2015-04-02T07:14:59.187 回答
3

只要您使用标准 Volley 库而没有任何自定义 HttpStack 或对其进行修改(gradle 依赖项:compile 'com.mcxiaoke.volley:library:1.0.15'),那么您需要包含的唯一更改是Request 类中的 parseNetworkResponse 方法(假设您使用 Gson 转换为 Json,这来自我编写的自定义 GsonRequest 类)。

@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
    try {
        final String json = new String(
                response.data, HttpHeaderParser.parseCharset(response.headers));

        if (TextUtils.isEmpty(json)) {
            return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
        }

        return Response.success(gson.fromJson(json, clazz), null);
    } catch (UnsupportedEncodingException e) {
        return Response.error(new ParseError(e));
    } catch (JsonSyntaxException e) {
        return Response.error(new ParseError(e));
    }
}
于 2015-09-30T22:34:55.190 回答