URLConnection - 读取响应后无法写入请求正文
URLConnection - Cannot write request body after response has been read
我有一组对象,我正在尝试 POST 到 API。第一个对象将按原样通过,然后我得到:
java.net.ProtocolException: cannot write request body after response has been read
我相当确定这只是我做事的顺序,但我仍在学习 Android 并且已经尝试了一个多小时了。
我想向你们寻求帮助!我需要收到对 POST 的每个响应,这样我就可以将其 psrse 用于稍后使用的 ID 字段。您会看到我在我的 FOR 循环中解析它,然后将 ID 存储在一个列表中,稍后我将循环访问该列表。
下面 POST 的代码:
try {
url = new URL("##Edited Out##");
conn = (HttpsURLConnection) url.openConnection();
// Create the SSL connection
sc = SSLContext.getInstance("TLS");
sc.init(null, null, new SecureRandom());
conn.setSSLSocketFactory(sc.getSocketFactory());
// Use this if you need SSL authentication
String userpass = "##Edited Out##:##Edited Out##";
String basicAuth = "Basic " + Base64.encodeToString(userpass.getBytes(), Base64.DEFAULT);
conn.setRequestProperty("Authorization", basicAuth);
conn.setRequestProperty("Content-Type", "application/json;odata=verbose");
// set Timeout and method
conn.setReadTimeout(7000);
conn.setConnectTimeout(7000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
JSONObject juo = new JSONObject();
for (int i = 0; i<objects.size(); i++){
juo.put("Field1", "Data for field 1 here");
juo.put("Field2", "Data for field 2 here");
juo.put("Field3", "Data for field 3 here");
wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(juo.toString());
wr.flush();
wr.close();
Log.d("ITEM STRING", juo.toString());
BufferedReader br = new BufferedReader(new InputStreamReader(
conn.getInputStream(), "utf-8"));
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
Log.d("HTTP BR", "" + sb.toString());
jObject = XML.toJSONObject(sb.toString());
Log.d("JSON OBJECT", jObject.toString());
JSONObject menuObject = jObject.getJSONObject("entry");
JSONObject contentObject = menuObject.getJSONObject("content");
JSONObject propertiesObject = contentObject.getJSONObject("m:properties");
JSONObject productObject = propertiesObject.getJSONObject("d:Product_Id");
String retProId = productObject.getString("content");
partIDs.add(retProId);
Log.d("PART ID", retProId);
}
int HttpResult = conn.getResponseCode();
Log.d("HTTP RESULT", String.valueOf(HttpResult));
Log.d("HTTP RESPONSE", conn.getResponseMessage());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
编辑:关于下面的重复评论
我收到的错误略有不同。它的原理我明白了,但是我的.getRespondeCode在我的for循环之外,它应该循环通过。但事实并非如此。
如果 objects.size>=2
会发生此错误
我需要获取每个对象的服务器响应字符串 POSTed,因为它包含我需要解析的 ID。
HTTP 协议基于请求-响应模式:您先发送请求,然后服务器响应。一旦服务器响应,您将无法再发送任何内容,这没有意义。
查看您的代码,您正在 for 循环中获取响应。当访问一个响应时,然后下一次循环抛出异常。如果你想创建多个请求,那么每次都应该创建新的 urlconnection。例如。
private void requestMethod(){
//your for loop goes here
}
private void backgroundOperation(/**required parameter*/){
// your httpurlconnection code goes here don't use for loop. use finally block to close connection also
}
我有一组对象,我正在尝试 POST 到 API。第一个对象将按原样通过,然后我得到:
java.net.ProtocolException: cannot write request body after response has been read
我相当确定这只是我做事的顺序,但我仍在学习 Android 并且已经尝试了一个多小时了。
我想向你们寻求帮助!我需要收到对 POST 的每个响应,这样我就可以将其 psrse 用于稍后使用的 ID 字段。您会看到我在我的 FOR 循环中解析它,然后将 ID 存储在一个列表中,稍后我将循环访问该列表。
下面 POST 的代码:
try {
url = new URL("##Edited Out##");
conn = (HttpsURLConnection) url.openConnection();
// Create the SSL connection
sc = SSLContext.getInstance("TLS");
sc.init(null, null, new SecureRandom());
conn.setSSLSocketFactory(sc.getSocketFactory());
// Use this if you need SSL authentication
String userpass = "##Edited Out##:##Edited Out##";
String basicAuth = "Basic " + Base64.encodeToString(userpass.getBytes(), Base64.DEFAULT);
conn.setRequestProperty("Authorization", basicAuth);
conn.setRequestProperty("Content-Type", "application/json;odata=verbose");
// set Timeout and method
conn.setReadTimeout(7000);
conn.setConnectTimeout(7000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
JSONObject juo = new JSONObject();
for (int i = 0; i<objects.size(); i++){
juo.put("Field1", "Data for field 1 here");
juo.put("Field2", "Data for field 2 here");
juo.put("Field3", "Data for field 3 here");
wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(juo.toString());
wr.flush();
wr.close();
Log.d("ITEM STRING", juo.toString());
BufferedReader br = new BufferedReader(new InputStreamReader(
conn.getInputStream(), "utf-8"));
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
Log.d("HTTP BR", "" + sb.toString());
jObject = XML.toJSONObject(sb.toString());
Log.d("JSON OBJECT", jObject.toString());
JSONObject menuObject = jObject.getJSONObject("entry");
JSONObject contentObject = menuObject.getJSONObject("content");
JSONObject propertiesObject = contentObject.getJSONObject("m:properties");
JSONObject productObject = propertiesObject.getJSONObject("d:Product_Id");
String retProId = productObject.getString("content");
partIDs.add(retProId);
Log.d("PART ID", retProId);
}
int HttpResult = conn.getResponseCode();
Log.d("HTTP RESULT", String.valueOf(HttpResult));
Log.d("HTTP RESPONSE", conn.getResponseMessage());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
编辑:关于下面的重复评论 我收到的错误略有不同。它的原理我明白了,但是我的.getRespondeCode在我的for循环之外,它应该循环通过。但事实并非如此。
如果 objects.size>=2
会发生此错误我需要获取每个对象的服务器响应字符串 POSTed,因为它包含我需要解析的 ID。
HTTP 协议基于请求-响应模式:您先发送请求,然后服务器响应。一旦服务器响应,您将无法再发送任何内容,这没有意义。
查看您的代码,您正在 for 循环中获取响应。当访问一个响应时,然后下一次循环抛出异常。如果你想创建多个请求,那么每次都应该创建新的 urlconnection。例如。
private void requestMethod(){
//your for loop goes here
}
private void backgroundOperation(/**required parameter*/){
// your httpurlconnection code goes here don't use for loop. use finally block to close connection also
}