【问题标题】:Accessing all response headers using volley api in android application在 android 应用程序中使用 volley api 访问所有响应标头
【发布时间】:2017-06-25 21:41:32
【问题描述】:

在通过 HttpResponse 在 android 中使用 HttpClient 进行连接时,能够获取所有可能的“set-cookie”标头值(JESSIONID 和 XSCRF-TOKEN)。检查下面的屏幕截图。

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

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

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

【问题讨论】:

    标签: android cookies header android-volley


    【解决方案1】:

    有解决方法:

    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
        }
    

    【讨论】:

      【解决方案2】:

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

      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&lt;String, String&gt;,它不能包含具有不同值的相同键。所以你总是只有最后一个饼干。
      cookie 设置的标准告诉我们应该用 ; 分隔 cookie,例如,如果你想在请求 cookie 中包含 2 个键值,你应该像这样放置它们: Cookies: k1=v1;k2=v2

      解决方案:
      在您的情况下,您有两个选择。

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

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

      2 - 获取 Volley 源代码并更改错误的方法并再次制作一个固定的 .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;
      }
      

      【讨论】:

      • 感谢 Sepehr Behroozi,Google Android 开发人员应该解决这个问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      • 1970-01-01
      • 2021-01-24
      • 2012-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多