C'è un modo per ottenere l'intestazione http di risposta non elaborata?Ottenere intestazioni di risposta HTTP non corretti
Il metodo getHeaderField()
non funziona per me, perché il server sputa più "Set-Cookie" e alcuni di essi vengono persi.
C'è un modo per ottenere l'intestazione http di risposta non elaborata?Ottenere intestazioni di risposta HTTP non corretti
Il metodo getHeaderField()
non funziona per me, perché il server sputa più "Set-Cookie" e alcuni di essi vengono persi.
Il metodo
getHeaderField()
non funziona per me
Stai chiedendo questo nel contesto di java.net.URLConnection
, è vero? No, non è possibile ottenere le intestazioni di risposta HTTP non elaborate con URLconnection
. Dovrai tornare alla programmazione di livello basso Socket. Ecco un SSCCE, basta copiare e non rovinare.
package com.stackoverflow.q2307291;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
public class Test {
public static void main(String[] args) throws IOException {
String hostname = "stackoverflow.com";
int port = 80;
Socket socket = null;
PrintWriter writer = null;
BufferedReader reader = null;
try {
socket = new Socket(hostname, port);
writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.println("GET/HTTP/1.1");
writer.println("Host: " + hostname);
writer.println("Accept: */*");
writer.println("User-Agent: Java"); // Be honest.
writer.println(""); // Important, else the server will expect that there's more into the request.
writer.flush();
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
for (String line; (line = reader.readLine()) != null;) {
if (line.isEmpty()) break; // Stop when headers are completed. We're not interested in all the HTML.
System.out.println(line);
}
} finally {
if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
if (writer != null) { writer.close(); }
if (socket != null) try { socket.close(); } catch (IOException logOrIgnore) {}
}
}
}
Per evitare in modo da essere sovraccaricati da tutti di provare questo frammento di codice, ecco come l'output sarà simile:
HTTP/1.1 200 OK Cache-Control: private Content-Type: text/html; charset=utf-8 Expires: Sun, 21 Feb 2010 20:39:08 GMT Server: Microsoft-IIS/7.5 Date: Sun, 21 Feb 2010 20:39:07 GMT Connection: close Content-Length: 208969
Per ulteriori informazioni sull'invio richieste HTTP il modo di basso livello, leggere il HTTP specification.
Tuttavia, probabilmente si desidera utilizzare il metodo getHeaderFields()
per recuperare un'intestazione con più valori. Il getHeaderField()
vale a dire restituisce solo l'ultimo valore, come da documento API collegato.
List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
Heys stai dicendo che 'java.net.URLConnection' è basato su questi metodi? – Pacerier
"L'ottenimento delle intestazioni di risposta HTTP non è possibile con' URLConnection' "? Cosa restituisce 'getHeaderField (int)'? – erickson
@erickson: analizza le intestazioni delle risposte non elaborate e restituisce il valore per l'intestazione dell'indice specificato. Non restituisce le intestazioni di risposta non elaborata esattamente come mostrato nella citazione nella mia risposta. Credo che tu stia interpretando erroneamente "crudo" nel contesto di questa domanda. Hai comunque letto il suggerimento "getHeaderFields()" in fondo alla mia risposta? A proposito: non ho votato in difetto la tua risposta :) – BalusC
Il modo più semplice è quello di utilizzare il metodo di URLConnection
getHeaderFields()
. Ecco un codice che fa qualcosa di equivalente.
static String[] getHeaders(HttpURLConnection con, String header) {
List<String> values = new ArrayList<String>();
int idx = (con.getHeaderFieldKey(0) == null) ? 1 : 0;
while (true) {
String key = con.getHeaderFieldKey(idx);
if (key == null)
break;
if (header.equalsIgnoreCase(key))
values.add(con.getHeaderField(idx));
++idx;
}
return values.toArray(new String[values.size()]);
}
Questa risposta non è corretta vero? – Pacerier
@Pacerier Hai provato? Cosa hai trovato sbagliato? – erickson
Mi stanno svuotando le intestazioni 'Set-Cookie'. Due o tre di loro, a seconda di ciò che l'altra parte invia. Altre intestazioni funzionano bene. Il problema non sembra essere nella stampa poiché 'connection.getRequestProperties()' mostra 'Set-Cookies = [,]'. I cookie sono 'Sicuro; HTTPOnly', ma questo non dovrebbe importare in Java. Strano, non è vero? – maaartinus
Non esattamente 'crudo', ma conciso:
for (Map.Entry<String, List<String>> k : myHttpURLConnection.getHeaderFields().entrySet()) {
System.out.println(k.toString());
}
Se ti preoccupi che alcune delle intestazioni sono perdersi uso:
for (Map.Entry<String, List<String>> k : myHttpURLConnection.getHeaderFields().entrySet()) {
for (String v : k.getValue()){
System.out.println(k.getKey() + ":" + v);
}
}
PS: Meglio tardi che mai. :)
Non ho testato il tuo esempio, ma credo che getHeaderFields restituisca solo un valore per un campo. Questo porta a problemi, se ottieni più campi con lo stesso nome, ad esempio "Set-Cookies" è uno di questi. – p4553d
@ p4553d - ecco perché entrySet restituisce un elenco
In ritardo per la festa, ma ecco la soluzione più semplice. Attua semplicemente CookieStore. (O utilizzare l'implementazione di default e lasciare che prendersi cura di aggiungere i cookie per le chiamate successive.)
http://docs.oracle.com/javase/7/docs/api/java/net/CookieStore.html
impostare il proprio negozio di biscotto come gestore di cookie predefinito
CookieManager cookieManager = new CookieManager(new MyCookieStore(), CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cookieManager);
E ogni nuovo cookie ti apparirà in add() nel tuo CookieStore. Ho avuto lo stesso problema con i param sovrascrivibili avendo lo stesso nome "Set-Cookie" in una singola richiesta, e ora ho sia il cookie che il sessionId.
Sembra che tu stia utilizzando una libreria come Apache HTTP Client? Sarebbe utile affermare che, in tal caso, poiché presumo che tu stia chiedendo se quella particolare biblioteca abbia un tale metodo. –
Sarebbe utile, ma penso che non stia usando il client Apache ma la libreria standard Java: http://docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html#getHeaderField(java.lang. String) – thermz