Java Spring框架,在请求结束前开始使用HTTP请求体

时间:2016-09-06 09:10:14

标签: java spring http request streaming

在Java Spring框架中,如何在请求完成之前创建一个以块为单位开始使用HTTP请求主体的端点?

似乎是默认行为i,在请求结束之前不会执行端点方法。

以下Node.js服务器开始使用请求体,如何对Java Spring框架做同样的事情?

const http = require('http');

const server = http.createServer((request, response) => {
  request.on('data', (chunk) => {
    console.log('NEW CHUNK: ', chunk.toString().length);
  });

  request.on('end', () => {
    response.end('done');
  });
});

server.listen(3000);

输出:

NEW CHUNK:  65189
NEW CHUNK:  65536
NEW CHUNK:  65536
NEW CHUNK:  65536
NEW CHUNK:  54212

1 个答案:

答案 0 :(得分:1)

我不确定是否有一个用spring映射chunked请求的解决方案我会做的是这样的:

package fr.viveris.xchange.cloud.storage.controller.synchro.v1;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class ChunkController {

private static final int EOS = -1;

    @RequestMapping(method = RequestMethod.POST)
    public ResponseEntity<Void> upload(final HttpServletRequest request, @RequestParam final int chunkSize) {
        try (InputStream in = request.getInputStream()) {
            byte[] readBuffer = new byte[chunkSize];
            int nbByteRead = 0;
            int remainingByteToChunk = chunkSize;
            while ((nbByteRead = in.read(readBuffer, chunkSize - remainingByteToChunk, remainingByteToChunk)) != EOS) {
                remainingByteToChunk -= nbByteRead;
                if (remainingByteToChunk == 0) {
                    byte[] chunk = Arrays.copyOf(readBuffer, readBuffer.length);
                    remainingByteToChunk = readBuffer.length;
                    // do something with the chunk.
                }
            }
            if (remainingByteToChunk != chunkSize) {
                byte[] lastChunk = Arrays.copyOf(readBuffer, readBuffer.length - remainingByteToChunk);
                //  do something with the last chunk
            }
            return new ResponseEntity<>(HttpStatus.OK);
        } catch (IOException e) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

或者你可以为块的大小定义一个常量。

您也可以忽略块的大小,只处理in.read的结果,直到流结束。