Android HttpURLConnect-使用GSON流传输而不发送内容的带有JSON的Http PUT

Android HttpURLConnect-使用GSON流传输而不发送内容的带有JSON的Http PUT,android,json,stream,gson,httpurlconnection,Android,Json,Stream,Gson,Httpurlconnection,我是Android开发的新手。我正在尝试构建一个Android http客户端,它向发送JSON的.NET Web API发出请求 我正在使用: GSON 2.3将JSON序列化为反序列化,因为它支持流式传输,因为JSONObject不能很好地处理大型JSON(它试图在内存中的字符串中加载整个JSON,因此占用了太多内存)。我试着跟着 Android Studio中的Android API 17 HttpURLConnection作为Http推荐的客户端 我正试图请求一个带有JSON的htt

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

我正在使用:

  • GSON 2.3将JSON序列化为反序列化,因为它支持流式传输,因为JSONObject不能很好地处理大型JSON(它试图在内存中的字符串中加载整个JSON,因此占用了太多内存)。我试着跟着
  • Android Studio中的Android API 17
  • HttpURLConnection作为Http推荐的客户端
我正试图请求一个带有JSON的http PUT,服务器端的Web API得到了http请求,但它找不到任何JSON,所以我肯定错过了一些我看不到的东西。。我甚至考虑过它在这里所说的:关于使用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()

toJson(myData,MobileData.class,writer)

然后,它将抛出一个非法状态异常嵌套问题。我只是想澄清一下,我正在尝试使用混合GSON编写来利用混合流和对象模型访问。因此,我试图获取MobileAmsData复杂对象,将其流序列化为JSON和http,并将其放到远程服务器

EDITED2:如果使用

字符串parsed=gson.toJson(myData,MobileData.class)


在这里苦苦挣扎之后,我发现:

  • 如果想要充分利用Android设备内存使用率低的优势,就必须使用分块传输编码。因此,HttpURLConnection应该设置分块流模式(系统默认值为0,或者根据需要设置任何其他字节数,例如1000)
urlConnection.setChunkedStreamingMode(0)

  • 使用ChunkedStreamingMode时,Http请求将使用传输编码Http头,但内容长度将为0这似乎是服务器端出现问题的原因,因为如果请求没有内容长度,我的ASP.NET Web Api方法无法反序列化JSON

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

总而言之,上面的代码是有效的,它能够通过GSON将JSON流式传输到输出流并使用分块编码传输发送HTTP PUT请求。。。但这不是有效的代码,如果内存使用是一个问题,应该重新处理以逐行序列化

{
   "Things1":[

   ],
   "Things2":[

   ],
   "Things3":[

   ],
   "Things4":[

   ],

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