views:

1429

answers:

4

In the following code, I have verified that connecting to a URL from within an applet preserves the browser's session if JDK's URLConnection class is used. However, this is not the case if Apache's HttpClient library is used. Does anyone know why? Alternatively, is there a way for me to set the connection instance to be used by an HttpClient instance?

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();
     }
    }
}
A: 

Possible causes, is that you have not done a disconnect() when using URLConnection, however, the apache library will close the connection when you are done with it.

Ram
I don't understand. URLConnection is behaving as expected. You seem to be under the impression that I am having problems with it.
Chry Cheng
I mean that the Apache HTTPClient disconnects and thereby you lose your session information. And connections made thereafter will totally be a new one with a new session info.
Ram
The test code clearly shows that I use HttpClient only once. I probably should have provided the server-side test code as well as the output that shows how I concluded that that single usage of HttpClient failed.
Chry Cheng
Yes, that would be useful information. From what you've posted, it's not immediately clear just what you mean by "failed".
jdigital
A: 

I think that you're using an older version of HttpClient. Check out HttpClient's website.

In the current API, you can use HttpState in the execute method, so that your code could look like this:

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

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

In the next execution, pass the same "state" object, and you'll get the credentials and cookies preserved.

Aviad Ben Dov
If you have to stay with your version of HttpClient, tell me what it is - and maybe there's an equivalent in your version.
Aviad Ben Dov
+1  A: 

You must send the jsessionid cookie or rewrite your URL to use the jsessionid.

That's the way the server knows your session.

If you generate the applet tag in a JSP page dinamically you can pass the jsessionid value to the applet as a parameter and then use it.

post.setHeader("Cookie", "jsessionid=" + jsessionidValue );
oscargm
+1  A: 

This is a common problem with libraries implementing their own URL connection via Socket. Apparently, the JRE implementation of the URLConnection class can get to the browser information directly. We had to employ the technique as mentioned by oscargm above, i.e. on the appserver writing the request cookies to be the parameters to the applet AND getting to the browser's document cookies using JavaScript (this is for the case of SSO where the set of cookies may not be the same because of the intermediate agent -- proxy servers). Note that if the cookies are HttpOnly -- the javascript code will fail.

qd
I'd like to accept your answer but the check thing is not showing up.
Chry Cheng