Der Anschluss an eine URL innerhalb eines Applets mit Httpclient des Apache vs mit der URLConnection JDK
-
06-07-2019 - |
Frage
Im folgenden Code habe ich festgestellt, dass innerhalb eines Applets zu einer URL verbindet die Sitzung des Browsers erhält, wenn JDK URLConnection Klasse verwendet wird. Dies ist jedoch nicht der Fall, wenn Apache Httpclient-Bibliothek verwendet wird. Weiß jemand, warum? Alternativ gibt es eine Möglichkeit für mich die Verbindung Instanz festgelegt durch eine Httpclient-Instanz verwendet werden?
import java.applet.Applet;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import javax.net.ssl.SSLException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
public class HttpClientTesterApplet extends Applet {
private static final long serialVersionUID = -1599714556710568947L;
public void testHttpClient() throws ClientProtocolException, IOException,
URISyntaxException {
URL url = new URL(String.format("%s://localhost:%s/%s/testHttpClient",
getParameter("protocol"), getParameter("port"),
getParameter("context")));
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url.toURI());
System.out.println("Executing request " + post.getURI());
try {
System.out
.println(client.execute(post, new BasicResponseHandler()));
} catch (SSLException e) {
System.out.println(e.getMessage());
}
System.out.println("Executed request " + post.getURI());
System.out.println("Opening connection " + url);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
System.out.println("Opened connection " + url);
urlConnection.setRequestMethod("POST");
System.out.println("Connecting");
urlConnection.connect();
System.out.println("Connected");
InputStream inputStream = urlConnection.getInputStream();
try {
while (inputStream.read() != -1) {
System.out.println("Reading");
}
} finally {
inputStream.close();
}
}
}
Lösung
Dies ist ein häufiges Problem mit Bibliotheken ihre eigene URL-Verbindung über Socket-Implementierung. Offenbar kann die JRE Umsetzung der URLConnection Klasse an den Browser Informationen erhalten, direkt. Wir hatten die Technik zu verwenden, wie oben von oscargm erwähnt, auf der appserver, dh die Anforderung Cookies Schreiben an das Applet die Parameter zu sein und sich an das Dokument Cookies im Browser JavaScript verwenden (dies ist für den Fall von SSO, wo der Satz von Cookies kann wegen des Zwischenmittels nicht gleich sein - Proxy-Server). Beachten Sie, dass, wenn die Cookies Httponly -. Der JavaScript-Code fehl
Andere Tipps
Sie müssen das jsessionid
Cookie oder neu schreiben Sie Ihre URL senden, um die jsessionid
zu verwenden.
Das ist die Art und Weise der Server die Sitzung kennt.
Wenn Sie den applet
Tag in einer JSP-Seite dynamisch generieren Sie die jsessionid
value zum Applet als Parameter übergeben können und dann verwenden.
post.setHeader("Cookie", "jsessionid=" + jsessionidValue );
Ich denke, dass Sie eine ältere Version von Httpclient verwenden. Schauen Sie sich Httpclient Webseite .
In der aktuellen API können Sie HttpState im Verfahren ausführen verwenden, so dass Ihr Code könnte wie folgt aussehen:
HttpClient client = new HttpClient();
HttpMethod method = new PostMethod(url.toURI());
HttpState state = new HttpState();
client.executeMethod(HttpConfiguration.ANY_HOST_CONFIGURATION, method, state);
In der nächsten Ausführung übergeben Sie das gleiche „Zustand“ Objekt, und Sie werden die Anmeldeinformationen und Cookies erhalten erhalten.
Mögliche Ursachen, ist, dass Sie nicht eine disconnect (), wenn URLConnection Verwendung jedoch getan haben, die Apache-Bibliothek wird die Verbindung schließen, wenn Sie mit ihm fertig sind.
Thi ist ein wichtiges Thema.
Die Standard-java.net.URLConnection Klasse integriert sich nahtlos in das Java-Plug-in und dem Web-Browser, erben kann Sitzung, HTTP Authentifizierungs-Token, Proxy-Anschlüsse, etc.
Die Jungs von Apache Commons einen groben Fehler, wenn sie Httpclient von Socket zu implementieren entschieden (dh von Grund auf neu) anstatt nur die Entwicklung auf dem Standard java.net.URL * Klassen. Httpclient erbt nicht von java.net.URLConnection so dass es nicht seine erweiterte Enterprise-Funktionen erben kann.
Vielleicht Open Source-Projekte sind nicht so klug, wie sie denken.
Ich kann es ohne Umweg Cookies als Argumente aus der Web-Seite mit diesem Code funktioniert:
private String retrieveCookies(URL url) throws IOException, URISyntaxException
{
String cookieValue = null;
CookieHandler handler = CookieHandler.getDefault();
if (handler != null) {
Map<String, List<String>> headers = handler.get(url.toURI(), new HashMap<String, List<String>>());
List<String> cookiesList = headers.get("Cookie");
if (cookiesList != null)
{
for (String v : cookiesList) {
if (cookieValue == null)
cookieValue = v;
else
cookieValue = cookieValue + ";" + v;
}
}
}
return cookieValue;
}
...
httppost.addHeader("Cookie", retrieveCookies(new URL(uploadUrl)));
JDK Klasse CookieHandler kann zum Glück die Cookies von den „System“ Speichern erhalten. In diesem Fall ist es der Browser zu speichern, accesed über die Java-Plugin.
Eine Art "Handarbeit", aber es funktioniert.
Hinweis: Ich fand den Code hier