5 Stimmen

Senden von Cookies mit HTTP-Anforderung in Java

Ich versuche, ein bestimmtes Cookie in einem Java-Client zu bekommen, indem ich eine Reihe von Http-Anfragen erstelle. Es sieht so aus, als ob ich ein gültiges Cookie vom Server erhalte, aber wenn ich eine Anfrage an die endgültige URL mit dem scheinbar gültigen Cookie sende, sollte ich einige Zeilen XML in der Antwort erhalten, aber die Antwort ist leer, weil das Cookie falsch ist oder ungültig ist, weil eine Sitzung geschlossen wurde oder ein anderes Problem, das ich nicht herausfinden kann. Das vom Server ausgegebene Cookie läuft am Ende der Sitzung ab.

Es scheint mir, dass das Cookie gültig ist, denn wenn ich dieselben Aufrufe in Firefox mache, wird ein ähnliches Cookie mit demselben Namen und den 3 ersten gleichen Buchstaben und derselben Länge in Firefox gespeichert, das auch am Ende der Sitzung abläuft. Wenn ich dann eine Anfrage an die endgültige URL mit nur diesem bestimmten in Firefox gespeicherten Cookie mache (alle anderen Cookies entfernt), wird das XML schön auf der Seite dargestellt.

Habt ihr Ideen, was ich in diesem Code falsch mache? Noch etwas, wenn ich den Wert aus dem sehr ähnlichen Cookie verwende, das in Firefox generiert und gespeichert wird, gibt die letzte Anfrage tatsächlich XML-Feedback in der HTTP-Antwort zurück.

// Validieren
        url = new URL(URL_VALIDATE);
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("Cookie", cookie);
        conn.connect();

        String headerName = null;
        for (int i = 1; (headerName = conn.getHeaderFieldKey(i)) != null; i++) {
            if (headerName.equals("Set-Cookie")) {
                if (conn.getHeaderField(i).startsWith("JSESSIONID")) {
                    cookie = conn.getHeaderField(i).substring(0, conn.getHeaderField(i).indexOf(";")).trim();
                }
            }
        }

        // XML abrufen
        url = new URL(URL_XML_TOTALS);
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("Cookie", cookie);
        conn.connect();

        // Antwort abrufen
        StringBuffer answer = new StringBuffer();
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {
            answer.append(line);
        }
        reader.close();

        // Antwort ausgeben
        System.out.println(answer.toString())

1 Stimmen

Hast du jemals daran gedacht, einfach zu Commons HttpClient zu wechseln? hc.apache.org/httpclient-3.x

1 Stimmen

Es sieht so aus, als ob du das alles sehr manuell machst. Ich weiß nicht, wie du das Session-Verfallsdatum verwaltet. Wenn du deinen Server-Code in einem Servlet hättest, wäre es viel einfacher. Ist das eine Option?

6voto

McDowell Punkte 105255

Ich fühle mich ein wenig zu faul, um deinen Code zu debuggen, aber du könntest in Betracht ziehen, dass ein CookieHandler die Arbeit für dich erledigt. Hier ist einer, den ich schon früher gemacht habe:

public class MyCookieHandler extends CookieHandler {
  private final Map> cookies = 
                                            new HashMap>();

  @Override public Map> get(URI uri,
      Map> requestHeaders) throws IOException {
    Map> ret = new HashMap>();
    synchronized (cookies) {
      List store = cookies.get(uri.getHost());
      if (store != null) {
        store = Collections.unmodifiableList(store);
        ret.put("Cookie", store);
      }
    }
    return Collections.unmodifiableMap(ret);
  }

  @Override public void put(URI uri, Map> responseHeaders)
      throws IOException {
    List newCookies = responseHeaders.get("Set-Cookie");
    if (newCookies != null) {
      synchronized (cookies) {
        List store = cookies.get(uri.getHost());
        if (store == null) {
          store = new ArrayList();
          cookies.put(uri.getHost(), store);
        }
        store.addAll(newCookies);
      }
    }
  }
}

Der CookieHandler geht davon aus, dass dein Cookie-Handling global für die JVM ist; wenn du pro-Thread-Client-Sitzungen oder eine andere kompliziertere Transaktionsverarbeitung möchtest, bist du vielleicht besser dran, bei deinem manuellen Ansatz zu bleiben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X