HttpURLConnect - 使用JSON的Http PUT使用GSON流不发送内容

时间:2014-09-29 20:54:22

标签: android json stream gson httpurlconnection

我是Android开发的新手。我正在尝试构建一个Android http客户端,它向发送JSON的.NET Web API发出请求。

我正在使用:

我正在尝试使用JSON请求http PUT并且服务器端的Web API获取http请求但它无法找到任何JSON,所以我必须遗漏一些我看不到的东西..我甚至考虑过什么它在这里说:How to stream a JSON object to a HttpURLConnection POST request关于使用connect()方法尽管 HttpURLConnection文档没有提到它

我的代码:

public void sendData(final String id, final int count, final MobileData myData)
        throws WebApiException {
    HttpURLConnection urlConnection = null;
    final String urlSend = "http://myIISapi" + "/" + id + "?count=" + count;
    try {
        final URL url = new URL(urlSend);
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setDoOutput(true);
        urlConnection.setChunkedStreamingMode(0); //gets system default chunk size

        urlConnection.setRequestMethod("PUT");
        urlConnection.setRequestProperty("Content-Type", "application/json");
        urlConnection.setRequestProperty("Accept", "application/json");
        urlConnection.connect(); //necessary?


        final OutputStream outputStream = new BufferedOutputStream(urlConnection.getOutputStream());
        final JsonWriter writer = new JsonWriter(new OutputStreamWriter(outputStream, "UTF-8"));
        writer.setIndent("  ");
        Gson gson = new Gson();
        //String parsed = gson.toJson(amsData, MobileAmsData.class);
        gson.toJson(myData, MobileData.class, writer);
        writer.flush();
        writer.close();

        final int statusCode = urlConnection.getResponseCode();
        LOG.info("sendData server responded with status code = " + statusCode);
        if (HttpURLConnection.HTTP_OK != statusCode) {
            throw new WebApiException("Server did not accept data. Status code: " + statusCode);
        }
    }
    catch (Exception e) {
        throw new WebApiException("Unable to send PUT request", e);
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
    }
}

我错过了一些强制性标题吗?我对发送JSON的流媒体方式有点困惑所以问题可能存在。最后,是否有可能通过这样的流数据实际存在多个HTTP请求,服务器应该考虑数据是否正在流式传输?或者流式传输仅在客户端以单个http请求的构建方式发生?

谢谢你们!

已编辑:如果我明确告诉JsonWriter

  

writer.beginObject();

之前的

  

gson.toJson(myData,MobileData.class,writer);

然后会抛出 IllegalStateException - 嵌套问题。为了澄清,我正在尝试使用混合GSON写入来利用混合流和&对象模型访问。所以我试图抓住MobileAmsData复杂对象,将其串行化为JSON,并将其发送到远程服务器。

EDITED2:如果使用

进行序列化,我尝试发送的JSON看起来像这样
  

String parsed = gson.toJson(myData,MobileData.class);

{
   "Things1":[

   ],
   "Things2":[

   ],
   "Things3":[

   ],
   "Things4":[

   ],

   "Things1Count":0,
   "Things2Count":0,
   "Things3Count":0,
   "Things4Count":0,
   "Count":2,
   "BarcodeCount":1
}

1 个答案:

答案 0 :(得分:2)

在经历了很多挣扎之后,我发现了这一点:

  • 如果希望充分利用Android设备中的低内存使用率,则必须使用Chunked Transfer Encoding。所以HttpURLConnection应该设置一个分块的流模式(0表示系统的默认值或任何其他字节数,例如1000,根据需要)
  

urlConnection.setChunkedStreamingMode(0);

  • 使用ChunkedStreamingMode时,Http请求将使用Transfer-Encoding HTTP标头但Content-Length将为0. 这似乎是导致服务器端出现问题的问题。如果请求没有内容长度,则.NET Web Api方法无法反序列化JSON

  • 如果我想充分利用GSON流模式,我需要添加一些智能功能来逐行写入JsonWriter(输出流)而不是整个对象。如果我打开流,然后立即解析Json并关闭流我认为内存使用率将高于转换为Json并逐行写入时的内存使用量。 (这在GSON文档中对我来说不是很清楚)

总结一下,上面的代码是WORKS,它能够将带有GSON流JSON的HTTP PUT请求发送到输出流并使用分块编码传输......但是它不是高效的代码,应该重新编写为序列化行如果内存使用是一个问题,请按行。