Java 如何将JSON对象流式传输到HttpURLConnection POST请求
我看不出这个代码有什么问题:Java 如何将JSON对象流式传输到HttpURLConnection POST请求,java,post,httpurlconnection,Java,Post,Httpurlconnection,我看不出这个代码有什么问题: JSONObject msg; //passed in as a parameter to this method HttpURLConnection httpCon = (HttpURLConnection) url.openConnection(); httpCon.setDoOutput(true); httpCon.setDoInput(true); httpCon.setUseCaches(false); httpCon.setRequestPrope
JSONObject msg; //passed in as a parameter to this method
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setRequestProperty( "Content-Type", "application/json" );
httpCon.setRequestProperty("Accept", "application/json");
httpCon.setRequestMethod("POST");
OutputStream os = httpCon.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
msg.write(osw);
osw.flush();
osw.close();
os.close(); //probably overkill
在服务器上,我没有收到任何帖子内容,一个长度为零的字符串。试试看
...
httpCon.setRequestMethod("POST");
httpCon.connect(); // Note the connect() here
...
OutputStream os = httpCon.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
...
osw.write(msg.toString());
osw.flush();
osw.close();
发送数据
要检索数据,请尝试:
BufferedReader br = new BufferedReader(new InputStreamReader( httpCon.getInputStream(),"utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
System.out.println(""+sb.toString());
HttpURLConnection
使用起来很麻烦。使用一个围绕HttpURLConnection的小包装器,您可以这样编写:
JSONObject消息//作为参数传递到此方法
Webb=Webb.create();
JSONObject结果=webb.post(“http://my-url/path/to/res")
.useCaches(错误)
.body(msg)
.ensureSuccess()
.asJsonObject()
.getBody();
如果您不喜欢,在提供的链接上有一个替代库的列表
为什么我们每天都要编写相同的样板代码?顺便说一句,上面的代码可读性更强,也不容易出错HttpURLConnection
有一个糟糕的接口。这个必须包起来 遵循以下示例:
public static PricesResponse getResponse(EventRequestRaw request) {
// String urlParameters = "param1=a¶m2=b¶m3=c";
String urlParameters = Piping.serialize(request);
HttpURLConnection conn = RestClient.getPOSTConnection(endPoint, urlParameters);
PricesResponse response = null;
try {
// POST
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
// RESPONSE
BufferedReader reader = new BufferedReader(new InputStreamReader((conn.getInputStream()), StandardCharsets.UTF_8));
String json = Buffering.getString(reader);
response = (PricesResponse) Piping.deserialize(json, PricesResponse.class);
writer.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
conn.disconnect();
System.out.println("PricesClient: " + response.toString());
return response;
}
public static HttpURLConnection getPOSTConnection(String endPoint, String urlParameters) {
return RestClient.getConnection(endPoint, "POST", urlParameters);
}
public static HttpURLConnection getConnection(String endPoint, String method, String urlParameters) {
System.out.println("ENDPOINT " + endPoint + " METHOD " + method);
HttpURLConnection conn = null;
try {
URL url = new URL(endPoint);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(method);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "text/plain");
} catch (IOException e) {
e.printStackTrace();
}
return conn;
}
在asynctask中的doitbackground中调用此方法,而不使用json字符串将数据发布到服务器
class PostLogin extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
String response = null;
Uri.Builder builder= new Uri.Builder().appendQueryParameter("username","amit").appendQueryParameter("password", "amit");
String parm=builder.build().getEncodedQuery();
try
{
response = postData("your url here/",parm);
}catch (Exception e)
{
e.printStackTrace();
}
Log.d("test", "response string is:" + response);
return response;
}
}
private String postData(String path, String param)throws IOException {
StringBuffer response = null;
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
// connection.setRequestProperty("Content-Type", "application/json");
// connection.setRequestProperty("Accept", "application/json");
OutputStream out = connection.getOutputStream();
out.write(param.getBytes());
out.flush();
out.close();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
response = new StringBuffer();
while ((line = br.readLine()) != null) {
response.append(line);
}
br.close();
}
return response.toString();
}
class PostLogin扩展了异步任务{
@凌驾
受保护字符串doInBackground(无效…参数){
字符串响应=null;
Uri.Builder=new Uri.Builder().appendQueryParameter(“用户名”、“amit”).appendQueryParameter(“密码”、“amit”);
字符串parm=builder.build().getEncodedQuery();
尝试
{
response=postData(“你的url在这里/”,parm);
}捕获(例外e)
{
e、 printStackTrace();
}
Log.d(“测试”,“响应字符串为:”+响应);
返回响应;
}
}
私有字符串postData(字符串路径、字符串参数)引发IOException{
StringBuffer响应=null;
URL=新URL(路径);
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setRequestMethod(“POST”);
connection.setDoOutput(真);
//setRequestProperty(“内容类型”、“应用程序/json”);
//setRequestProperty(“接受”、“应用程序/json”);
OutputStream out=connection.getOutputStream();
out.write(param.getBytes());
out.flush();
out.close();
int responseCode=connection.getResponseCode();
if(responseCode==HttpURLConnection.HTTP\u确定){
BufferedReader br=新的BufferedReader(新的InputStreamReader(connection.getInputStream());
弦线;
响应=新的StringBuffer();
而((line=br.readLine())!=null){
响应。追加(行);
}
br.close();
}
返回response.toString();
}
我不使用“msg.toString()”的原因是我不想再复制数据。我一直使用msg.write()来写入文件写入程序,因此我知道它可以正确地写入流。另一个区别是调用“connect”,我会试试。是的,“connect”似乎解决了这个问题(这很奇怪,因为服务器收到了一个请求,所以建立了一个连接,但显然“connect”实际上发送了正文?在连接的位置上有限制吗?在头之后和getOutputStream之前?JavaDoc说“URLConnection对象经历两个阶段:首先创建,然后连接。在创建之后和连接之前,可以指定各种选项(例如doInput和UseCaches)。连接后,尝试设置它们是一个错误。依赖于连接的操作,如getContentLength,将在必要时隐式执行连接。“。可能close()强制执行connect(),但flush()会提前执行?此外,甚至close()也会OSW上的已触发。这个.body是否处理流式JSON而不是类似DOM的JsonObject序列化JSON的方式?我的意思是,如果我想使用GSON流式处理JSON,那么这个Webb是否处理它?看起来非常有趣,我想我会尝试一下,因为GZIP压缩很简单。但是我找不到任何关于支持JSON的信息streaming json看看。谢谢@realavaloro。如果我们能找到解决方案,我会更新答案。哇,看起来非常好而且简单。我如何获得HTTP响应代码?比如200,401..?@RageCompex您可以访问状态代码和其他我知道看起来很奇怪的东西,但是JSONObject类有一个write方法,您可以将Writer对象传递给该方法,该类将自己写入流。这比转换为字符串然后写入字符串要高效得多。这并不会真正产生d不同的是,在这种情况下,我们可以将任何内容发送给编写器,测试也是一样的。错误在于获取连接。
class PostLogin extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
String response = null;
Uri.Builder builder= new Uri.Builder().appendQueryParameter("username","amit").appendQueryParameter("password", "amit");
String parm=builder.build().getEncodedQuery();
try
{
response = postData("your url here/",parm);
}catch (Exception e)
{
e.printStackTrace();
}
Log.d("test", "response string is:" + response);
return response;
}
}
private String postData(String path, String param)throws IOException {
StringBuffer response = null;
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
// connection.setRequestProperty("Content-Type", "application/json");
// connection.setRequestProperty("Accept", "application/json");
OutputStream out = connection.getOutputStream();
out.write(param.getBytes());
out.flush();
out.close();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
response = new StringBuffer();
while ((line = br.readLine()) != null) {
response.append(line);
}
br.close();
}
return response.toString();
}