在Android应用程序中使用volley api访问所有响应头

时间:2017-02-08 10:16:25

标签: android cookies header android-volley

在使用HttpResponse中的HttpClient进行连接时,能够获得所有可能的“set-cookie”标头值(JESSIONID和XSCRF-TOKEN)。请查看下面的截图。 HttpResponse header

现在使用android studio和volley api进行连接,我只得到“set-cookie”标题的单个值(仅限JESSIONID)。参见下文: Volley response header

我还检查了https://groups.google.com/forum/#!topic/volley-users/rNTlV-LORzY。 必须在volley api jar项目中进行更改。但不知道如何编辑凌空api。如果有任何其他解决方案,请提供指导。

请使用volley api帮助检索“set-cookie”的多个值。

2 个答案:

答案 0 :(得分:3)

<强>问题:
不幸的是,问题出在了Volley内部。我遇到了这个问题,经过多次搜索,我发现在convertHeaders类中有一个名为BasicNetwork的方法可以处理这样的标题:

protected static Map<String, String> convertHeaders(Header[] headers) {
    Map<String, String> result = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
    for (int i = 0; i < headers.length; i++) {
        result.put(headers[i].getName(), headers[i].getValue());
    }
    return result;
}

您会看到结果为Map<String, String>,但不能包含具有不同值的相同键。所以你总是只有最后一个cookie cookie设置的标准告诉我们,我们应该将cookie与;分开,例如,如果您想在请求cookie中包含2个键值,您应该将它们放在这样: Cookies: k1=v1;k2=v2

<强>解决方案:
在您的情况下,您有两种选择。

1 - 更改服务器端的代码,以便响应仅包含 1 Set-Cookie分隔的键值;您的回复示例

Set-Cookie: JESSIONID=qZtQ...;Path=/;HttpOnly;XSRF-TOKEN=6c65...

2 - 获取Volley源代码并更改该buggy方法并再次修复.jar!这个选项是我最喜欢的,因为你没有触及服务器的响应

我对此方法的实现是:

protected static Map<String, String> convertHeaders(Header[] headers) {
    TreeMap result = new TreeMap(String.CASE_INSENSITIVE_ORDER);

    for(int i = 0; i < headers.length; ++i) {
        String headerName = headers[i].getName();
        if(!result.containsKey(headerName)) {
            result.put(headers[i].getName(), headers[i].getValue());
        } else {
            String value = (String)result.get(headerName);
            String mergedValue = value + ";" + headers[i].getValue();
            result.remove(headerName);
            result.put(headerName, mergedValue);
        }
    }

    return result;
}

答案 1 :(得分:0)

有以下解决方法:

implementation "com.android.volley:volley:1.1.0"

“ NetworkResponse(和Cache.Entry)现在包含“ allHeaders”字段,该字段是服务器返回的所有标头的原始列表,因此可以按名称包含重复项。”

来源:https://github.com/google/volley/issues/21

示例:

    private static final String COOKIE_KEY = "Set-Cookie";
    private static final String COOKIE_NAME = "NameOfOneOfTheCookies";

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        handleCookies(response);
        String parsed;
        try {
            parsed = new String(response.data, "utf-8");
        } catch (UnsupportedEncodingException e) {
            parsed = new String(response.data);
        }
        return Response.success(parsed,
                HttpHeaderParser.parseCacheHeaders(response));
    }

    private void handleCookies(NetworkResponse response) {
        for (Header header : response.allHeaders) {
            if (header.getName().equals(COOKIE_KEY) && header.getValue().startsWith(COOKIE_NAME)) {
                getCookies(response);
            }
        }
    }

    private void getCookies(NetworkResponse response) {
        ArrayList<String> cookiesList = new ArrayList<>();
        for (Header header : response.allHeaders) {
            if (header.getName().equals(COOKIE_KEY)) {
                cookiesList.add(header.getValue());
            }
        }
        // TODO Do something with the cookiesList
    }