Connexion à une URL depuis une applet à l'aide du HttpClient d'Apache ou de l'URLConnection du JDK

StackOverflow https://stackoverflow.com/questions/1216165

Question

Dans le code suivant, j'ai vérifié que la connexion à une URL à partir d'une applet préserve la session du navigateur si la classe URLConnection de JDK est utilisée. Cependant, ce n'est pas le cas si la bibliothèque HttpClient d'Apache est utilisée. Quelqu'un sait-il pourquoi? Sinon, est-il possible pour moi de définir l’instance de connexion à utiliser par une instance HttpClient?

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();
        }
    }
}
Était-ce utile?

La solution

Il s'agit d'un problème courant avec les bibliothèques implémentant leur propre connexion URL via Socket. Apparemment, l'implémentation JRE de la classe URLConnection peut accéder directement aux informations du navigateur. Nous avons dû utiliser la technique mentionnée par oscargm ci-dessus, c'est-à-dire que le serveur d'applications écrivant les cookies de requête doit constituer les paramètres de l'applet ET accéder aux cookies de document du navigateur à l'aide de JavaScript (c'est le cas de SSO où l'ensemble de cookies peut être utilisé). ne pas être la même en raison de l'agent intermédiaire - serveurs proxy). Notez que si les cookies sont HttpOnly, le code javascript échouera.

Autres conseils

Vous devez envoyer le cookie jsessionid ou réécrire votre URL pour utiliser le jsessionid .

C’est ainsi que le serveur connaît votre session.

Si vous générez la balise applet dans une page JSP de manière dynamique, vous pouvez transmettre la valeur jsessionid à l'applet en tant que paramètre, puis l'utiliser.

post.setHeader("Cookie", "jsessionid=" + jsessionidValue );

Je pense que vous utilisez une version plus ancienne de HttpClient. Consultez le le site Web de HttpClient .

Dans l'API actuelle, vous pouvez utiliser HttpState dans la méthode execute pour que votre code ressemble à ceci:

HttpClient client = new HttpClient();
HttpMethod method = new PostMethod(url.toURI());
HttpState state = new HttpState();

client.executeMethod(HttpConfiguration.ANY_HOST_CONFIGURATION, method, state);

Lors de la prochaine exécution, transmettez le même " état " objet, et vous obtiendrez les informations d'identification et les cookies préservés.

Les causes possibles sont que vous n’avez pas effectué de disconnect () lors de l’utilisation de URLConnection. Cependant, la bibliothèque apache ferme la connexion lorsque vous avez terminé.

C’est un problème important.

La classe standard java.net.URLConnection s’intègre de manière transparente au plug-in java et au navigateur Web, peut hériter de la session, des jetons d’authentification HTTP, des connecteurs de proxy, etc.

Les employés d’Apache Commons ont commis une grave erreur en décidant d’implémenter HttpClient from Socket (c’est-à-dire de zéro) au lieu de simplement développer au-dessus des classes standard java.net.URL *. HttpClient n'hérite pas de java.net.URLConnection et ne peut donc pas hériter de ses fonctionnalités d'entreprise avancées.

Peut-être que les projets OpenSource ne sont pas aussi intelligents qu'ils le pensent.

Je pourrais le faire fonctionner sans transmettre de cookies en tant qu'arguments de la page Web contenant ce code:

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

La classe CookieHandler de JDK peut heureusement obtenir les cookies du & system; system " le magasin. Dans ce cas, il s’agit du magasin du navigateur, accessible via le plugin Java.

Type de "travail manuel", mais cela fonctionne.

REMARQUE: j'ai trouvé le code . ici

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top