vert.xweb(scala):从路由器读取作为流的多部分文件上传,而不保存到磁盘

qyzbxkaa  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(291)

我知道通过vert.xWeb处理文件上传是可能的 Router 简单地使用这样的东西:

myRouter.post("/upload")
    .handler(BodyHandler.create("myUploadDirectory")))
    .handler { context =>
        // do something with the uploaded files and respond to the request
    }

但是,这会将文件保存在本地服务器上(甚至可能是网络共享)。暂时将小文件缓冲在磁盘上,然后将它们批量移动到另一个存储区,这可能是非常好的,但对于非常大的文件(例如,多个千兆字节)来说,情况并非如此。
例如,将上传的文件读取为字节流,并将其直接写入最终存储区,然后能够优雅地处理失败和成功,所有这些都是从 Router ?
代理上载这将避免使存储对客户端公开访问,并且可能允许对上载过程进行更细粒度的控制,而不仅仅是在服务器上创建本地文件或公开对象/blob存储。
编辑:
我知道另一种方法是这样做,在处理我的请求之前,将文件上传作为一种特殊情况来处理 Router :

val myHttpServer = myVertx.createHttpServer()

      myHttpServer.requestHandler(request => {
        if(request.absoluteURI().contains("/upload")) {
          request.setExpectMultipart(true)
          request.handler { buffer =>
            // upload part of the file
          }
          request.endHandler { end =>
            // perform some action when the upload is done
          }
        } else
          myRouter.handle(request)
      })

然而,正如你所看到的,它看起来相当混乱。如果用一只手来处理,会干净得多 Router.post() 或者类似的东西。
我是不是做错了什么?
我试过做以下的事情,但没有效果(我只得到一个HTTP500,日志中没有有用的错误)。就连那个 exceptionHandler 被解雇了。

myRouter.post("/upload")
          .handler { context =>
            context.request.setExpectMultipart(true)
            context.request.uploadHandler { upload =>
              upload.handler { buffer =>
                // send chunk to backend
              }
              upload.endHandler { _ =>
                // upload successful
              }
              upload.exceptionHandler { e =>
                // handle the exception
              }
            }
          }

解决方案:
原来我加了一个 BodyHandlerRouter 在添加我的路线之前。这是因为我希望能够在其他post请求中接收json主体,而不希望必须键入 .handler(BodyHandler.create()) 在每个接收到json的路由之前。
然而,正如班上所说。。。尸体随后被处理,这意味着我将无法添加 UploadHandler 对请求的响应。

kyxcudwk

kyxcudwk1#

我不熟悉scala,但这里有一个java解决方案:

router.post("/upload").handler(rc -> {
  HttpServerRequest req = rc.request();
  req.setExpectMultipart(true);
  req.uploadHandler(upload -> {
    upload.exceptionHandler(cause -> {
      req.response().setChunked(true).end("Upload failed");
    });

    upload.endHandler(v -> {
      req.response().setChunked(true).end("Successfully uploaded file");
    });
    upload.handler(buffer -> {
      // Send to backend
    });
  });
});

相关问题