我正在使用 vertx.io 编写分段文件上传的代码。
在Spring boot中我的代码如下。我想在 vertex.io 中写类似的内容
@RequestMapping(value = "/upload", headers=("content-type=multipart/*") ,method = RequestMethod.POST)
public ImportExportResponse upload(@RequestParam("file") MultipartFile inputFile){
log.info(" upload service method starts ");
ImportExportResponse response = new ImportExportResponse();
FileOutputStream fileOutputStream=null;
try{
File outputFile = new File(FILE_LOCATION+inputFile.getOriginalFilename());
fileOutputStream = new FileOutputStream(outputFile);
fileOutputStream.write(inputFile.getBytes());
fileOutputStream.close();
response.setStatus(ImportExportConstants.ResponseStatus.SUCCESS.name());
response.setErrorMessage(EMPTY);
}catch (Exception e) {
log.error("Exception while upload the file . "+e.getMessage());
response.setStatus(ImportExportConstants.ResponseStatus.ERROR.name());
response.setErrorMessage(errorMap.get(SYSTEM_ERROR_CODE));
}
log.info(" upload service method ends. file is copied to a temp folder ");
return response;
}
这里是相同的,但是在 vert.x 中:
Router router = Router.router(vertx);
// Enable multipart form data parsing
router.post("/upload").handler(BodyHandler.create()
.setUploadsDirectory(FILE_LOCATION));
// handle the form
router.post("/upload").handler(ctx -> {
// in your example you only handle 1 file upload, here you can handle
// any number of uploads
for (FileUpload f : ctx.fileUploads()) {
// do whatever you need to do with the file (it is already saved
// on the directory you wanted...
System.out.println("Filename: " + f.fileName());
System.out.println("Size: " + f.size());
}
ctx.response().end();
});
有关更多示例,您可以随时查看 vertx-examples 存储库。
对于 99.9% 的用例,Paulo Lopes 的答案是绝对正确的。
它的主要问题是上传的文件存储在文件系统上的临时空间中 - 您必须确保有足够的空间可用于用户将上传的所有文件;您必须确保对最大上传大小设置适当的限制,以便攻击者无法对您进行 DoS;您必须处理该文件并在完成后将其删除。
如果所有这些都让您担心并且您愿意投入额外的工作,这里介绍了如何获取上传的 Vert.x
ReadStream
- 然后您可以从中读取数据并将数据推送到有意义的地方,而不会产生任何麻烦与使用RoutingContext.fileUploads()
相关的存储和IO:
如果您不希望
BodyHandler
使用上传内容并将其保存到本地文件 - 不要让它处理上传。主要有以下三种方法:
BodyHandler.create(false)
创建不支持文件上传的正文处理程序。这里我将演示选项3。
Router router = Router.router(vertx);
// Pause the request reading so we can register for handling the body later
router.route("/*").handler(ctx -> { ctx.request().pause(); ctx.next(); });
// handle the upload
router.post("/upload").handler(ctx -> {
ctx.request().setExpectMultipart(true) // this sets up the upload handlers
.uploadHandler(upload -> { // register our upload handler
// this handler will be called once for each file found in the request
var filename = upload.filename();
var contentType = upload.contentType();
consumeUpload(upload.pipe()); // upload is a ReadStream, so read it
})
.endHandler(__ -> {
// somehow verify that all uploads were consumed successfully
// (or figure out the correct error response)
ctx.response().end(); // do something more meaningful here
})
.resume(); // after we have setup our handlers, resume the request
});
// have a body handler to handle all the other routes
// it will resume the request automatically so the body will be available
// for outher routes
router.route("/*").handler(BodyHandler.create());
// ... what ever else routes you have