来自公务员的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是基于公务员
- 强大