阅读分块数据

时间:2014-01-09 11:17:17

标签: java http tomcat servlets chunked-encoding

我有一个发送分块数据的客户端。我的服务器应该读取该数据。在服务器上,我正在使用Tomcat 7.0.42并希望通过现有的servlet加载这些数据。

我正在查找google以查看是否可以获取任何读取分块数据的示例,遗憾的是我没有偶然发现任何内容。

我发现由Tomcat提供的Apache Http Client或ChunkedInputFilter提供的ChunkedInputStream很少引用。但我找不到任何关于如何最好地使用它们的正确例子。

如果你们中的任何人有阅读/解析分块数据的经验,请分享这些数据。

使用的Java版本 - 1.7.0.45

在我现有的servlet代码中,我一直在使用NIO通过post处理简单请求。但是现在如果客户端将传输编码设置为chunked,我需要专门处理它。所以我有一个分叉代码。如下所示,

inputStream = httpServletRequest.getInputStream();

if ("chunked".equals(getRequestHeader(httpServletRequest, "Transfer-Encoding"))) {
   // Need to process chunked data
} else {
   // normal request data
   if (inputStream != null) {
     int contentLength = httpServletRequest.getContentLength()
     if (contentLength <= 0) {
        return new byte[0];
     }
     ReadableByteChannel channel = Channels.newChannel(inputStream);
     byte[] postData = new byte[contentLength];
     ByteBuffer buf = ByteBuffer.allocateDirect(contentLength);
     int numRead = 0;
     int counter = 0;
     while (numRead >= 0) {
        buf.rewind();
        numRead = channel.read(buf);
        buf.rewind();
        for (int i = 0; i < numRead; i++) {
           postData[counter++] = buf.get();
        }
     }
     return postData;
  }
}

因此,如果您观察到,正常请求案例基于可用的“内容长度”,而对于分块编码,则不存在。因此,处理分块数据的另一个过程。

谢谢,

维基

2 个答案:

答案 0 :(得分:0)

请参阅HTTP 1/1 Chunked Transfer Coding

你的servlet将提供可变大小的块。你将获得第一行中每个块的大小。协议很简单,所以你可以自己实现它。

答案 1 :(得分:-1)

遵循基于NIO的代码为我工作,

    ReadableByteChannel channel = Channels.newChannel(chunkedInputStream);

    // content length is not known upfront, hence a initial size
    int bufferLength = 2048;

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ByteBuffer byteBuffer = ByteBuffer.allocate(bufferLength);

    int numRead = 0;
    while (numRead >= 0) {
        byteBuffer.rewind();
        //Read bytes from the channel
        numRead = channel.read(byteBuffer);
        byteBuffer.rewind();

        if (numRead > 0) {
            byte[] dataBytes = byteBuffer.array();
            baos.write(dataBytes, 0, dataBytes.length);
        }

        byteBuffer.clear();
    }

    return baos.toByteArray();