在大多数情况下,我的HTTP请求没有问题。但是,他们偶尔会挂起来。
我正在使用的代码设置为如果请求成功(响应代码为200或201),则调用screen.requestSucceeded()。如果请求失败,则调用screen.requestFailed()。
但是,当请求挂起时,它会在调用上述方法之一之前执行此操作。我的代码有问题吗?我应该使用某种最佳做法来防止任何悬挂吗?
以下是我的代码。我将不胜感激任何帮助。谢谢!
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 DialogRunner(
"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());
}
答案 0 :(得分:6)
没有任何痕迹,我只是在黑暗中拍摄。
尝试添加这2个电话,
System.setProperty("http.keepAlive", "false");
connection.setRequestProperty("Connection", "close");
Keep-alive是陈旧连接的常见原因。这些调用将禁用它。
答案 1 :(得分:2)
我没有看到代码有任何问题。可能是您的平台有间歇性错误,或者网站导致连接挂起。更改连接参数(例如保持活动状态)可能会有所帮助。
但是,即使设置了超时,套接字也可以无限期挂起 - 几年前,一位朋友通过拔出网线恰当地向我展示了这一点 - 我的程序只是挂在那里,即使SO_TIMEOUT设置为30秒。 / p>
作为“最佳实践”,您可以通过将所有网络通信移动到单独的线程来避免挂起应用程序。如果将每个请求包装为Runnable并将这些请求排队以进行执行,则可以保持对超时的控制(同步仍在java中,而不是阻塞本机I / O调用)。您可以在(比方说)30秒之后中断您的等待线程,以避免拖延您的应用程序。然后,您可以通知用户,或重试请求。因为请求是Runnable,所以可以将其从停滞的线程队列中删除,并将其安排在另一个线程上执行。
答案 2 :(得分:1)
我看到你有代码来处理发送“POST”类型的请求,但是没有任何东西可以在请求中写入POST数据。如果连接类型是“POST”,那么您应该在connection.getResponseCode()之前执行以下操作:
答案 3 :(得分:1)
我在黑莓OS 5.0上也注意到了这个问题。没有办法可靠地重现这一点。我们最终使用wait / notify和Timertask使用了额外的线程。