我正在尝试使用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();
}
更新
有时工作,有时不工作! 在一些项目上工作,在其他项目上没有! 完全相同的代码,每次都有相同的例外:已经连接了 为什么我每次都无法获得新的连接?
答案 0 :(得分:3)
我认为你的问题是:
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
我无法看到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;
}
我为任何编译错误道歉。没有IDE,我没用。我尽力证明了这一点。
我使用了Latin-1编码。如果这不适合你,你可以试试UTF-8。
您可以尝试的另一件事是完全放弃内容长度并致电
conn.setChunkedStreamingMode(0);
是的,我意识到getBytes()
电话和OutputStreamWriter
正在重复相同的过程。一旦解决了这个问题,你就可以继续工作。
答案 1 :(得分:1)
我似乎无法弄清楚为什么会出现“已经连接的错误”,但这是我用来发出POST请求的代码。我在发送请求后关闭输入/输出流和连接,这可能会对你有帮助(虽然我不确定)
try {
URL url = new URL(stringURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
connection.setRequestProperty("Accept","application/json");
//connection.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length));
//connection.setRequestProperty("Connection", "Keep-Alive");
connection.setReadTimeout(10*1000);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
//Request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(params[1]);
wr.flush();
wr.close();
//Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
response = new StringBuffer();
//Expecting answer of type JSON single line {"json_items":[{"status":"OK","message":"<Message>"}]}
while ((line = rd.readLine()) != null) {
response.append(line);
}
rd.close();
System.out.println(response.toString()+"\n");
connection.disconnect(); // close the connection after usage
} catch (Exception e){
System.out.println(this.getClass().getSimpleName() + " ERROR - Request failed");
}
答案 2 :(得分:0)