2016-10-30 3 views
1

ich nicht den Wert in diesem Verfahren Zurückgeben einer Karte < Listen <String> > anstatt einfach Karte < String sehen, String >Was den Punkt der URLConnection.getHeaderFields() Zurückgeben eines Map <String, List <String>>

ich erwartete Karte < Listen <String> > von Wert zu sein, wenn ein Web-Server mehr als einen Wert in einem bestimmten Header zurückgibt. Es ist zulässig, dass mehrere Werte als kommagetrennte Liste zurückgegeben werden. Das habe ich am häufigsten mit Cache-Control gesehen. Ich würde erwarten, dass jeder Wert ein Element in der Liste ist. Aber das ist nicht der Fall:

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); 
    } 
    } 
} 

Ausgang:

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

Die Cache-Control-Werte werden nur als ein einziger String zurückgegeben.

Also, gibt es irgendwelche Umstände, wo der Header-Wert Liste <String> von Nutzen ist?

Lösung:

ich ein Servlet auf Tomcat bin mit duplizierten http-Response-Header, um zu versuchen & zu erzeugen.

Im Servlet-Code, wiederholte Aufrufe mit HttpServletResponse.addHeader() mit duplizierten Header-Namen funktioniert nicht. Alle Header-Werte werden in einem einzelnen kommagetrennten Wert konsolidiert.

Dies ist jedoch nicht zum Hinzufügen von Cookies zulässig. Wenn ich HttpServletResponse.addCookie() mehrmals verwende, erhalte ich mehrere verschiedene Set-Cookie-Header. Diese enden tatsächlich als verschiedene Strings in der Liste.

+0

Wenn Sie fragen, warum die API auf diese Weise entworfen wurde, wird niemand in der Lage sein, eine definitive Antwort zu haben und die Frage auf der Grundlage von Meinungen zu formulieren. Weitere Informationen finden Sie unter [fragt nach "warum" in den Sprachspezifikationen, die immer noch als "primär auf Meinungen basieren", wenn sie offizielle Antworten haben können?] (Http://meta.stackoverflow.com/a/323382/1743880) und [Ist es subjektiv zu fragen, warum etwas in der Sprache nicht implementiert wurde?] (http://meta.stackoverflow.com/a/293819/1743880) – Tunaki

+0

Technisch gesprochen, ist es zulässig, HTTP-Header-Schlüssel zu wiederholen. Semantisch entspricht es einer Kommakettung. – chrylis

+0

@Tunaki In diesem Fall gibt es einen einfachen objektiven Grund. – EJP

Antwort

1
field_name: field_value1, field_value2, field_value3 

in HTTP-Header gibt 1 Zeichenfolge in der Liste der entsprechenden Map-Eintrag, während semantisch äquivalent

field_name: field_value1 
field_name: field_value2 
field_name: field_value3 

3 Saiten geben.

Es können jedoch nicht alle Werte mit demselben Feldnamen zu Feldwertlisten kombiniert werden. Zum Beispiel in RFC 7230 wir

Hinweis lesen können: In der Praxis des "Set-Cookie" Header-Feld ([RFC6265]) oft mehrfach in einer Antwortnachricht erscheint und verwendet nicht die Liste Syntax, Verletzung der oben genannten Anforderungen für mehrere Header Felder mit dem gleichen Namen. Da es nicht zu einem einzelnen Feldwert kombiniert werden kann, sollten Empfänger "Set-Cookie" als einen Sonderfall bei der Verarbeitung von Header-Feldern behandeln. (Siehe Anhang A.2.3 von [Kri2001] für Details.)

+1

True, aber der Text, den Sie zitieren, ist von RFC 7230, nicht RFC 2616. –

+0

Vielen Dank, Sie haben Recht, ich habe es korrigiert. – MarianD

5

Der Grund ist einfach, dass HTTP-Header sowohl wiederholt als auch mehrwertig sein können.

+1

Wenn es * mehrere * Cache-Control-Antwortkopffelder gibt, dann sollte die Liste mehrere Zeichenfolgen enthalten. –

+0

Julian: Weißt du, dass eine Seite wiederholte Header zurückgibt, um das zu testen? Ich habe versucht, eine solche Antwort über ein Servlet auf Tomcat mit duplizierten HttpServletResponse.addHeader() -Aufrufen zu erzeugen, aber als ich sie in Firefox ansehe, wurden sie alle in einer einzigen kommagetrennten Liste zusammengefasst. – rgh

+0

rhg: Es könnte sein, dass die Firefox-Entwickler-Tools dies nicht richtig anzeigen. Versuchen Sie Telnet oder redbot.org –

Verwandte Themen