URLConnection.getHeaderFields()返回Map <string,list <string>&gt;的重点是什么?

时间:2016-10-30 11:20:10

标签: java http

我无法在此方法中看到返回Map&lt; String List&lt; String&gt;&gt;的值而不仅仅是Map&lt; String,String&gt;

我期待Map&lt; String List&lt; String&gt;&gt;当Web服务器在给定标头中返回多个值时,它是有价值的。将几个值作为逗号分隔列表返回是合法的。我最经常使用Cache-Control看到这个。我希望每个值都是列表中的一个项目。然而,事实并非如此:

import java.net.*;
import java.io.*;
import java.util.*;

class URLConnectionDemo {
  private static final String DEFAULT_URL = "http://stackoverflow.com";
  public static void main(String[] args) {
    URL url; 
    URLConnection urlConnection;
    try { 
      url = new URL((args.length==0) ? DEFAULT_URL : args[0]); 
      urlConnection = url.openConnection();  
      Map<String, List<String>> headerMap = urlConnection.getHeaderFields();
      System.out.printf("Header count = %d\n", headerMap.size());
      for(String key:headerMap.keySet()){
        System.out.printf("%s:\n", key);
        List<String> valuesList = headerMap.get(key);
        for(String value:valuesList){
          System.out.printf("  %s\n", value);
        }
      }
    } catch (IOException e) {
      System.out.println(e);
    }
  }
}

输出:

Header count = 19
null:
  HTTP/1.1 200 OK
....many other headers....
Cache-Control:
  public, max-age=7

Cache-Control值只作为单个String返回。

那么,是否有任何情况下标题值List&lt; String&gt;有用吗?

解决方案:

我在Tomcat上使用servlet试试&amp;生成重复的http响应标头。

在servlet代码中,使用重复调用 HttpServletResponse.addHeader() 具有重复的标题名称不起作用。所有标头值都合并为一个逗号分隔值。

但是,不允许添加Cookie。如果我使用 HttpServletResponse.addCookie() 好几次,我得到了几个不同的Set-Cookie标头。这些确实最终成为列表中的独特字符串。

2 个答案:

答案 0 :(得分:5)

原因很简单,HTTP标头可以重复和多值。

答案 1 :(得分:1)

field_name: field_value1, field_value2, field_value3
HTTP Header中的

在相应的映射条目列表中给出1个字符串,而在语义上等效

field_name: field_value1
field_name: field_value2
field_name: field_value3

将提供3个字符串。

但是,并非具有相同字段名称的所有值都可以组合到字段值列表中。例如,在RFC 7230我们可以阅读

  

注意:实际上,经常会出现“Set-Cookie”标题字段([RFC6265])         在响应消息中多次出现并且不使用         列表语法,违反了多个标题的上述要求         具有相同名称的字段。既然它不能合并成一个         单个字段值,收件人应该处理“Set-Cookie”作为         处理标题字段时的特殊情况。 (见附录A.2.3         [Kri2001]详情。)