我正在尝试使用HttpURLConnection&通过HttpURLConnection的OutputStream发送JSON数据:
请参阅下面的课程:
package com.app.data.pojos;
import android.os.AsyncTask;
import android.util.Log;
import com.app.xyz.data.GDParser;
import com.app.xyz.model.GDUser;
import com.app.xyz.model.GDUserStatus;
import com.app.xyz.utils.APrefs;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Created by arynaim on 10/12/17.
*/
public class PostUserStatus extends AsyncTask<String, Void, GDUserStatusResponse> {
private static final String TAG = "PostUserStatus";
private GDUser gdUser;
public PostUserStatus(GDUser gdUser) {
this.gdUser = gdUser;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected GDUserStatusResponse doInBackground(String... urls) {
Log.i(TAG,"doInBackground(), gDUserStatusResponse url:"+urls[0]);
HttpURLConnection httpURLConnection = null;
GDUserStatus gdUserStatus = null;
JsonElement jsonElemnt = null;
JsonObject jsonObject = null;
GDUserStatusResponse gDUserStatusResponse = null;
try {
URL url = new URL(urls[0]);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Content-length", "0");
httpURLConnection.setUseCaches(false);
httpURLConnection.setAllowUserInteraction(false);
httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpURLConnection.setRequestProperty("Authorization", new APrefs().getNMToken());
//httpURLConnection.connect();
JSONObject userIdJsonObject = new JSONObject();
userIdJsonObject.put("userID",getGdUser().getUserId());
//post json via OutputStream
OutputStream os = httpURLConnection.getOutputStream();
os.write(userIdJsonObject.toString().getBytes());
os.flush();
Log.i(TAG,"doInBackground(), http request"+url.toString());
int status = httpURLConnection.getResponseCode();
switch (status) {
case 200:
Log.i(TAG,"doInBackground(), http response status:"+status);
BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
jsonElemnt = new JsonParser().parse(sb.toString());
jsonObject = jsonElemnt.getAsJsonObject();
gdUserStatus = new GDParser().parseStatusResponse(jsonObject);
gDUserStatusResponse = new GDUserStatusResponse();
gDUserStatusResponse.setGdUserStatus(gdUserStatus);
br.close();
break;
default:
Log.e(TAG,"doInBackground(), http response error status:"+status);
//TODO: handle error responses
//TODO: if stale token refresh & try again
break;
}
} catch (IOException ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (httpURLConnection != null) {
try {
httpURLConnection.disconnect();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
return gDUserStatusResponse;
}//end doInBackgroud
protected void onPostExecute(GDUserStatusResponse gDUserStatusResponse) {
Log.i(TAG,"onPostExecute(), gDUserStatusResponse:"+gDUserStatusResponse);
}
public GDUser getGdUser() {
return gdUser;
}
public void setGdUser(GDUser gdUser) {
this.gdUser = gdUser;
}
}
但是当我写信给
时os.write(userIdJsonObject.toString().getBytes());
我遇到了这个例外:
10-13 16:30:46.737 15395-17467/com.app.xyz I/PostUserStatus: doInBackground(), gDUserStatusResponse url:https://development.xyz.com/api/v1/users/status
10-13 16:30:46.741 15395-17467/com.app.xyz I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
10-13 16:30:46.741 15395-17467/com.app.xyz I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
10-13 16:30:46.833 15395-17467/com.app.xyz W/System.err: java.net.ProtocolException: exceeded content-length limit of 0 bytes
10-13 16:30:46.833 15395-17467/com.app.xyz W/System.err: at com.android.okhttp.internal.http.RetryableSink.write(RetryableSink.java:58)
10-13 16:30:46.833 15395-17467/com.app.xyz W/System.err: at com.android.okhttp.okio.RealBufferedSink.flush(RealBufferedSink.java:221)
10-13 16:30:46.833 15395-17467/com.app.xyz W/System.err: at com.android.okhttp.okio.RealBufferedSink$1.flush(RealBufferedSink.java:204)
10-13 16:30:46.833 15395-17467/com.app.xyz W/System.err: at com.app.xyz.data.pojos.PostUserStatus.doInBackground(PostUserStatus.java:63)
10-13 16:30:46.833 15395-17467/com.app.xyz W/System.err: at com.app.xyz.data.pojos.PostUserStatus.doInBackground(PostUserStatus.java:24)
10-13 16:30:46.833 15395-17467/com.app.xyz W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:304)
10-13 16:30:46.833 15395-17467/com.app.xyz W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-13 16:30:46.833 15395-17467/com.app.xyz W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
10-13 16:30:46.833 15395-17467/com.app.xyz W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
10-13 16:30:46.834 15395-17467/com.app.xyz W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
10-13 16:30:46.834 15395-17467/com.app.xyz W/System.err: at java.lang.Thread.run(Thread.java:762)
10-13 16:30:46.835 15395-15395/com.app.xyz I/PostUserStatus: onPostExecute(), gDUserStatusResponse:null
我不想使用除Android / Java提供的基础之外的任何Http库。
答案 0 :(得分:1)
httpURLConnection.setRequestProperty("Content-length", "0");
删除它。您不需要使用此类设置内容长度,如果您打算发送邮件正文,则肯定不会为零。
httpURLConnection.setRequestMethod("POST");
将其替换为
httpURLConnection.setDoOutput(true);
否则你不允许做任何输出。
编辑对于怀疑论者,以下代码未设置内容长度,但在线路上发送Content-length: 9\r\n
标头后,“正确”返回405响应代码自动由HttpURLConnection
(以及POST
和Content-Type: application/x-www-form-urlencoded\r\n
标头的请求类型(均未由此代码设置):
URL url = new URL("http://google.com");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoOutput(true);
OutputStream out = conn.getOutputStream();
out.write("xxxx=yyyy".getBytes());
out.flush();
int responseCode = conn.getResponseCode();
System.out.println("responseCode="+responseCode);
InputStream in = (responseCode == 200) ? conn.getInputStream() : conn.getErrorStream();
int c;
while ((c = in.read()) != -1)
{
System.out.write(c);
}
in.close();
conn.disconnect();
答案 1 :(得分:-1)
我不知道POST +输出是可行的。但该错误特别提到了Content-Length 0。
JSONObject userIdJsonObject = new JSONObject();
userIdJsonObject.put("userID",getGdUser().getUserId());
byte[] content = userIdJsonObject.toString().getBytes();
httpURLConnection.setDoOutput(true);
httpURLConnection.setRequestProperty("Content-length",
String.valueOf(content.length));
...
OutputStream os = httpURLConnection.getOutputStream();
os.write(content);