开发者

Java HTTP Request Occasionally Hangs

For the majority of the time, my HTTP Requests work with no problem. However, occasionally they will hang.

The code that I am using is set up so that if the request succeeds (with a response code of 200 or 201), then call screen.requestSucceeded(). If the request fails, then call screen.requestFailed().

When the request hangs, however, it does so before one of the above methods are called. Is there something wrong with my code? Should I be using some sort of best practice to prevent any hanging?

The following is my code. I would appreciate any help. Thanks!

HttpConnection connection = (HttpConnection) Connector.open(url
                    + connectionParameters);

            connection.setRequestMethod(method);
            connection.setRequestProperty("WWW-Authenticate",
                    "OAuth realm=api.netflix.com");
            if (method.equals("POST") && postData != null) {
            connection.setRequestProperty("Content-Type",
                    "application/x-www-form-urlencoded");
            connection.setRequestProperty("Content-Length", Integer
                    .toString(postData.length));
            OutputStream requestOutput = connection.openOutputStream();
            requestOutput.write(postData);
            requestOutput.close();
        }
            int responseCode = connection.getResponseCode();
            System.out.println("RESPONSE CODE: " + responseCode);
            if (connection instanceof HttpsConnection) {
                HttpsConnection secureConnection = (HttpsConnection) connection;
                String issuer = secureConnection.getSecurityInfo()
                        .getServerCertificate().getIssuer();
                UiApplication.getUiApplication().invokeLater(
                        new Dialog开发者_开发技巧Runner(
                                "Secure Connection! Certificate issued by: "
                                        + issuer));

            }

            if (responseCode != 200 && responseCode != 201) {
                screen.requestFailed("Unexpected response code: "
                        + responseCode);
                connection.close();
                return;
            }

            String contentType = connection.getHeaderField("Content-type");
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            InputStream responseData = connection.openInputStream();
            byte[] buffer = new byte[20000];
            int bytesRead = 0;
            while ((bytesRead = responseData.read(buffer)) > 0) {
                baos.write(buffer, 0, bytesRead);
            }
            baos.close();
            connection.close();
            screen.requestSucceeded(baos.toByteArray(), contentType);
        } catch (IOException ex) {
            screen.requestFailed(ex.toString());
        }


Without any trace, I am just shooting in the dark.

Try to add this 2 calls,

System.setProperty("http.keepAlive", "false");

connection.setRequestProperty("Connection", "close");

Keep-alive is a common cause for stale connections. These calls will disable it.


I don't see any issues with the code. It could be that your platform has an intermittent bug, or that the website is causing the connection to hang. Changing connection parameters, such as keep alive, may help.

But, even with a timeout set, Sockets can hang indefinitely - a friend aptly demonstrated this to me some years ago by pulling out the network cable - my program just hung there forever, even with a SO_TIMEOUT set to 30 seconds.

As a "best practice", you can avoid hanging your application by moving all network communication to a separate thread. If you wrap up each request as a Runnable and queue these for exeuction, you maintain control over timeouts (synchronization is still in java, rather than a blocking native I/O call). You can interrupt your waiting thread after (say) 30s to avoid stalling your app. You could then either inform the user, or retry the request. Because the request is a Runnable, you can remove it from the stalled thread's queue and schedule it to execute on another thread.


I see you have code to handle sending a "POST" type request, however there is nothing that writes the POST data in the request. If the connection type is "POST", then you should be doing the following BEFORE the connection.getResponseCode():

  • set the "Content-Length" header
  • set the "Content-Type" header (which you're doing)
  • get an OutputStream from the connection using connection.openOutputStream()
  • write the POST (form) data to the OutputStream
  • close the OutputStream


I noticed this problem too on the blackberry OS 5.0. There is no way to reproduce this reliably. We ended up using additional thread using wait/notify along with Timertask.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜