来自公务员的pipe道stream请求职位

我将multipart/form-data发布到快速端点/data/upload ,如下所示:

 form(enctype="multipart/form-data", action="/data/upload", method="post") input(type="file", name="data") 

我正在使用busboy读取文件stream,这工作正常。 从那里,我想使用request npm模块将stream再次作为multipart/form-data到第二个Java后端。 JS客户端/ Java服务器代码如下:

  req.busboy.on('file', function (fieldName, fileStream, fileName, encoding, mimeType) { var reqBody = { url: server.baseURL + 'api/data', headers: { 'Connection': 'keep-alive', 'Content-Type': 'multipart/form-data' }, formData: { file: fileStream } }; request.post(reqBody, function (err, r, body) { // Do rendering stuff, handle callback }); }); 

Java端点(api / data)

 @POST @Consumes(MediaType.MULTIPART_FORM_DATA) public void addData(FormDataMultiPart formDataMultiPart) { // Handle multipart data here } 

我不认为我正在发送文件正确的multipart/form-data在这里…但我很难搞清楚如何从busboy直接从pipe道streamrequest没有读/写温度文件在客户端。 有任何想法吗?

Java堆栈跟踪:

 Apr 27, 2016 5:07:12 PM org.glassfish.jersey.filter.LoggingFilter log INFO: 3 * Server has received a request on thread qtp1631904921-24 3 > POST http://localhost:8080/api/data 3 > Connection: keep-alive 3 > Content-Length: 199 3 > Content-Type: multipart/form-data; boundary=--------------------------331473417509479560313628 3 > Host: localhost:8080 Apr 27, 2016 5:07:12 PM org.glassfish.jersey.filter.LoggingFilter log INFO: 3 * Server responded with a response on thread qtp1631904921-24 3 < 400 17:07:13.003 [qtp1631904921-24] WARN org.eclipse.jetty.http.HttpParser parseNext - bad HTTP parsed: 400 No URI for HttpChannelOverHttp@425137da{r=1,c=false,a=IDLE,uri=null} 

拉哈特build议的改变

  31 var reqBody = { 32 url: server.baseURL + 'data', 33 headers: { 34 'Connection': 'keep-alive', 35 'Content-Type': 'multipart/form-data' 36 } 37 }; 38 39 req.pipe(req.busboy.pipe(request.post(reqBody))); 

抛出错误:

 Error: Cannot pipe. Not readable. at Busboy.Writable.pipe (_stream_writable.js:154:22) 

这里的问题是您需要手动为分段上传提供“内容长度”,因为request (和底层form-data )无法自己弄清楚。 所以请求发送无效的Content-Length:199(对于任何传入的文件大小都是一样的),这会中断Java多部分分析器。

有多种解决方法:

1)使用传入请求'Content-Length'

 request.post({ url: server.baseURL + 'api/data', formData: { file: { value: fileStream, options: { knownLength: req.headers['content-length'] } } } }, function (err, r, body) { // Do rendering stuff, handle callback }) 

这会产生一些不正确的请求,因为传入的长度包括其他上传字段和边界,但是busboy能够parsing它,而没有任何投诉

2)等到文件完全被节点应用程序缓冲,然后发送给java

 var concat = require('concat-stream') req.busboy.on('file', function (fieldName, fileStream, fileName, encoding, mimeType) { fileStream.pipe(concat(function (fileBuffer) { request.post({ url: server.baseURL + 'api/data', formData: { file: fileBuffer } }, function (err, r, body) { // Do rendering stuff, handle callback }) })) }) 

这会增加应用程序的内存消耗,所以您需要小心并考虑使用busboy限制

3)上传前缓冲文件到磁盘(仅供参考)

  • 快递 + MULTER – 我build议使用快递服务器,它使事情更易于pipe理,而且MULTER是基于公务员
  • 强大