StreamingResponseBody
controller 以流的形式 返回数据
实现以流的形式返回数据,可以使用 StreamingResponseBody
。样例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Controller public class TestController2 {
@RequestMapping("/test") public ResponseEntity<StreamingResponseBody> handleRequest () {
StreamingResponseBody responseBody = new StreamingResponseBody() { @Override public void writeTo (OutputStream out) throws IOException { for (int i = 0; i < 1000; i++) { out.write( (Integer.toString(i) + " - ").getBytes() ); out.flush(); } } };
return new ResponseEntity(responseBody, HttpStatus.OK); } }
|
使用 ResponseEntity 的原因是 可以 添加各种响应头的状态码。
controller 以流的形式 接收数据
由于 MultipartResolver 会将浏览器传送来的流数据读取掉后保存到临时目录,这会造成流不可用。因此我们需要禁用这个功能。
1
| spring.servlet.multipart.enabled: false
|
接着是controller 如何读取流信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @RestController public class FileUploadController { @RequestMapping(value="/upload", method=RequestMethod.POST) public void upload(HttpServletRequest request) { try { boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (!isMultipart) { Response<String> responseObject = new Response<String>(false, "Not a multipart request.", ""); return responseObject; }
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iter = upload.getItemIterator(request); while (iter.hasNext()) { FileItemStream item = iter.next(); String name = item.getFieldName(); InputStream stream = item.openStream(); if (!item.isFormField()) { String filename = item.getName(); OutputStream out = new FileOutputStream(filename); IOUtils.copy(stream, out); stream.close(); out.close(); } } } catch (FileUploadException e) { return new Response<String>(false, "File upload error", e.toString()); } catch (IOException e) { return new Response<String>(false, "Internal server IO error", e.toString()); } } }
|
参考
ApacheCommonsFileUpload-streaming
Stack Overflow 大文件流处理