Vert.x 3.9.8大文件上传抛出UnsupportedOperationException问题咨询
大文件上传时Vert.x 3.9.8抛出UnsupportedOperationException但文件上传成功的问题分析
问题描述
我正在使用Vert.x 3.9.8进行文件上传,上传1GB以上的大文件时,会持续出现以下异常,但文件能成功上传。想请教这是什么问题?是否是Vert.x与Netty的版本冲突导致的?
异常信息
[2022-09-05 14:40:30 +0530][io.vertx.core.impl.ContextImpl] SEVERE: Unhandled exception java.lang.UnsupportedOperationException at io.vertx.core.http.impl.NettyFileUpload.definedLength(NettyFileUpload.java:179) at io.netty.handler.codec.http.multipart.HttpPostMultipartRequestDecoder.loadDataMultipartOptimized(HttpPostMultipartRequestDecoder.java:1188)
相关测试代码
public void helidonToVertxTest(TestContext testContext) { Async fileSentAsync = testContext.async(); Async fileReceivedAsync = testContext.async(); Router router = Router.router(vertx); router.route().handler(BodyHandler.create()); router.post("/api/upload").handler(routingContext -> { System.out.println("File/s has been received."); routingContext.response().end(); testContext.assertEquals(1, routingContext.fileUploads().size()); Iterator<FileUpload> iterator = routingContext.fileUploads().iterator(); FileUpload artifact = iterator.next(); Path savedArtifactsPath = Paths.get(artifact.uploadedFileName()); System.out.println("Uploaded file is "+savedArtifactsPath); testContext.assertTrue(savedArtifactsPath.toFile().exists()); fileReceivedAsync.complete(); }); vertx.createHttpServer().requestHandler(router).listen(8080, listenResult -> { if (listenResult.failed()) { System.out.println("Could not start HTTP server"); listenResult.cause().printStackTrace(); } else { System.out.println("Server started"); Path tempFile = createTemporaryFile(); String filename = "C:\\Users\\ansgupgu\\Pictures\\Movies\\cp.mp4"; sendFileHelidonUsingMultipart(fileSentAsync, Path.of(filename)); } }); fileSentAsync.await(60*1000); fileReceivedAsync.await(60*1000); }
问题分析与解决方案
这个异常并非Vert.x与Netty版本冲突导致,而是Vert.x 3.9.8对Netty的HttpPostMultipartRequestDecoder适配不完整引发的问题:
- 异常根源:Netty处理大文件上传时,会调用
loadDataMultipartOptimized方法尝试优化文件加载逻辑,该方法会调用Vert.x实现的NettyFileUpload.definedLength(),但在Vert.x 3.9.8中这个方法未做具体实现,直接抛出了UnsupportedOperationException。 - 文件仍能上传成功的原因:Netty捕获到该异常后,会自动降级使用常规的文件加载流程,因此最终文件可以完成上传,但异常会被Vert.x的上下文捕获并打印为SEVERE级别的日志。
解决办法
- 升级Vert.x版本:该问题在Vert.x 4.x系列版本中已被官方修复,完善了
NettyFileUpload类的方法实现,不会再触发此异常,这是最彻底的解决方案。 - 临时规避(无法升级时):可以通过自定义
BodyHandler的配置调整上传逻辑,比如设置BodyHandler.create().setDeleteUploadedFilesOnEnd(false),但这仅能减少日志干扰,无法从根源解决方法未实现的问题。
内容的提问来源于stack exchange,提问作者Anshul
相关产品推荐
相关产品推荐

