views:

32

answers:

2

Hi...

I want to call a secure webservice, using a cert that I have... the server takes a long time to authenticate with the cert, and, while this is ok the first time, the user will call it over and over again (in the same "session") and I feel I ought to be able to reuse the connection.

I have the following code.

System.setProperty("javax.net.ssl.trustStorePassword", "");
System.setProperty("javax.net.ssl.trustStore", "trusted.cacerts");
System.setProperty("javax.net.ssl.keyStorePassword", "mypassword");
System.setProperty("javax.net.ssl.keyStore", "trusted.clientcerts");

URL url = new URL("https://remoteserver:8443/testservice");
HttpsUrlConnection connection = (HttpsUrlConnecton)url.openConnection();
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/xml");
connection.setDoOutput(true);
OutputStream os = connection.getOutputStream();
os.write(bytes);

BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}

connection.disconnect();

This works great... but is slow. Just the authentication takes about 10 seconds. This internal authentication is typical here and that cannot be sped up. But can't I reuse it somehow? I tried put a loop around this code, between the url.connection and the disconnect, thinking I could just recall it again and again, but that fails (500). I have tried moving things around a bit, in order to do only some of the commands the first time, but it still fails. I read about keep-alive, but have not found any good examples of what this is, and how to use it (if that is even a valid way). If I do all of this via HTML, via firefox or ie, the browser is able to cache the cert, I guess, so every time after the first is blazzing fast. Can I emulate that some how?

Thanks, in advance.

A: 

Try just not calling connection.disconnect()... I don't think there should be any need for you to do that. You should, however, ensure that you close your reader when you're finished with it.

ColinD
This does not seem to work. If I do not call the disconnect, I get an error when I try to re-open the output stream (Protocol Exception: Cannot write output after reading input). I also tried just reusing the output stream (not closing it and not requesting it from the connection again)... That does not cause an error, but does not seem to actually write anything (hard to explain).
Doug Houck
@Doug: Are you trying to reuse the actual `HttpsURLConnection` object? Because I don't think you should be doing that. I think you should be calling `url.openConnection()` each time... and I'm pretty sure it can handle keeping the actual connection open for you.
ColinD
+1  A: 

better alternative is to use HttpClient and its connection pooling mechanism. also see if https keep-alive is going to help you

Pangea
hhmmm... trying this.... however, I cannot seem to get the right process to send my data. The Restful service I am calling takes in an XML string (@Consumes text/xml) on a Post. The PostMethod of the HttpClient, however, seems to want me to provide key/value pairs for parameters (again, all I have is the XML string). When I try to call it, the incorrect service gets invoked (web-form service). How do I use HttpClient to post an XML stream? Using HttpsURLConnection, I just wrote the outputstream. I cannot find this for PostMethod (or HttpClient).
Doug Houck
RequestEntity.. got it!!!... works for one call.. will try to reuse now. Thanks!
Doug Houck
seems to work.... doesn't fail anyway. A bit hard to tell sometimes if it is successfully reusing the connection as the server is very inconsistent in performance. But I like it!! thanks!!!!!
Doug Houck