Ham*_*boh 8 post android httpurlconnection
我正在尝试使用HttpUrlConnection进行POST调用,但没有成功.我经常收到'IllegalStateException:已连接'错误消息.我对重用连接不感兴趣.请检查我的代码并告诉我,如果我做错了什么:
public static final int CONNECTION_TIME_OUT = 10000;
public SimpleResponse callPost(String urlTo, Map<String, String> params) {
System.setProperty("http.keepAlive", "false");
HttpURLConnection conn = null;
SimpleResponse response = new SimpleResponse(0, null);
try {
URL url = new URL(urlTo);
conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
conn.setConnectTimeout(CONNECTION_TIME_OUT);
conn.setReadTimeout(CONNECTION_TIME_OUT);
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "close");
conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(paramsToString(params));
writer.flush();
writer.close();
os.close();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream in = conn.getInputStream();
String result = StringUtils.fromInputStream(in);
response = new SimpleResponse(responseCode, result);
in.close();
} else {
response = new SimpleResponse(responseCode, null);
}
} catch (Exception e) {
e.printStackTrace();
}
if (conn != null) {
conn.disconnect();
}
return response;
}
private String paramsToString(Map<String, String> params) {
if (params == null || params.isEmpty()) {
return "";
}
Uri.Builder builder = new Uri.Builder();
for (Map.Entry<String, String> entry : params.entrySet()) {
builder.appendQueryParameter(entry.getKey(), entry.getValue());
}
return builder.build().getEncodedQuery();
}
Run Code Online (Sandbox Code Playgroud)
更新:
有时工作,有时不工作!
在一些项目上工作,在其他项目上没有!
相同的代码,每次都有相同的异常:已经连接
为什么我每次都无法获得新的连接?
我认为你的问题是这样的:
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
Run Code Online (Sandbox Code Playgroud)
我看不到postDataBytes声明的位置,但由于您正在处理 中的参数paramsToString,我的猜测是它们没有关系。
现在,我不是 RFC 2616 (HTTP) 的专家,但我认为正在发生的情况是 的长度postDataBytes大于您的请求大小,因此服务器不会断开其一端的套接字。这些URLConnection对象被池化,因此当您获取连接对象时,其值已被清理以供重用,但实际连接仍然打开。
这是我认为你应该尝试的一些代码。如果它不能解决您的问题,我不会获得代表奖金,但它仍然肯定比您所拥有的更正确:
private static final String CHARSET = "ISO-8859-1"; // or try "UTF-8"
public SimpleResponse callPost(String urlTo, Map<String, String> params) {
// get rid of this...
// System.setProperty("http.keepAlive", "false");
HttpURLConnection conn = null;
SimpleResponse response = new SimpleResponse(0, null);
try {
URL url = new URL(urlTo);
conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
conn.setConnectTimeout(CONNECTION_TIME_OUT);
conn.setReadTimeout(CONNECTION_TIME_OUT);
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod("POST");
// ... and get rid of this
// conn.setRequestProperty("Connection", "close");
conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded; charset=" + CHARSET);
String content = paramsToString(params);
int length = content.getBytes(Charset.forName(CHARSET)).length;
conn.setRequestProperty("Content-Length", Integer.toString(length));
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, CHARSET));
writer.write(content);
writer.flush();
writer.close();
os.close();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream in = conn.getInputStream();
String result = StringUtils.fromInputStream(in);
response = new SimpleResponse(responseCode, result);
in.close();
} else {
response = new SimpleResponse(responseCode, null);
}
} catch (Exception e) {
e.printStackTrace();
}
if (conn != null) {
conn.disconnect();
}
return response;
}
Run Code Online (Sandbox Code Playgroud)
对于任何编译错误,我深表歉意。没有IDE我就没啥用。我尽我所能证明了这一点。
我使用Latin-1 编码。如果这不适合您,您可以尝试 UTF-8。
您可以尝试的另一件事是完全放弃内容长度并调用
conn.setChunkedStreamingMode(0);
Run Code Online (Sandbox Code Playgroud)
是的,我意识到getBytes()调用 和OutputStreamWriter正在重复相同的过程。一旦解决了这个问题,您就可以解决这个问题。
| 归档时间: |
|
| 查看次数: |
2714 次 |
| 最近记录: |