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



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

我正在使用:

  • GSON 2.3对JSON进行序列化和反序列化,因为它支持流式传输,因为JSONObject不能很好地处理大型JSON(当它试图将整个JSON加载到内存中的String中时,它使用了太多内存)。我试着跟随https://sites.google.com/site/gson/streaming
  • 安卓工作室内的安卓API 17
  • HttpURLConnection作为推荐的客户端Httphttp://developer.android.com/reference/java/net/HttpURLConnection.html

我试图用JSON请求一个http PUT,服务器端的Web API获得了http请求,但它找不到任何JSON,所以我一定错过了我看不到的东西。。我甚至考虑过它在这里所说的:如何将JSON对象流式传输到关于使用connect()方法的HttpURLConnection POST请求,尽管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);

那么它将抛出一个非法状态异常-嵌套问题。只是为了澄清,我试图使用混合GSON写作来利用混合流媒体&对象模型访问。因此,我试图获取MobileAmsData复杂对象,将其流序列化为JSON,并将其http PUT到远程服务器。

EDITED2:如果使用序列化,我尝试发送的JSON将如下所示

解析的字符串=gson.toJson(myData,MobileData.class);

{
   "Things1":[
   ],
   "Things2":[
   ],
   "Things3":[
   ],
   "Things4":[
   ],
   "Things1Count":0,
   "Things2Count":0,
   "Things3Count":0,
   "Things4Count":0,
   "Count":2,
   "BarcodeCount":1
}

在这里挣扎了很多之后,我发现了:

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

urlConnection.setChunkedStreamingMode(0);

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

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

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

相关内容

  • 没有找到相关文章

最新更新