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&param2=b&param3=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();
    }