You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus Resteasy reactive能否无需等待文件全量上传即可启动处理流程

Quarkus Resteasy Reactive 流式上传边传边处理方案

结论

可以实现无需等待文件完全上传完成就启动处理流程,你当前遇到的必须等上传完成才能处理的问题,是默认POJO表单映射的缓存机制导致的。

原因说明

默认情况下你使用FileUpload做POJO表单映射时,Quarkus会先把所有multipart内容完整缓存到本地临时文件或内存后,才会注入表单对象到接口方法,因此你只能在文件全部上传完成后才能拿到form.file对象开始处理。

实现方案

方案1:直接使用Vert.x原生API流式处理(推荐,改造成本最低)

直接注入RoutingContext监听上传事件,不用POJO表单映射,收到分片数据就可以立即处理:

import io.vertx.ext.web.RoutingContext
import jakarta.ws.rs.core.Context
import jakarta.ws.rs.core.MediaType
import jakarta.ws.rs.Consumes
import jakarta.ws.rs.POST
import jakarta.ws.rs.Path
import jakarta.ws.rs.core.Response

@Path("/upload")
class UploadResource {

    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    suspend fun upload(@Context routingContext: RoutingContext): Response {
        val request = routingContext.request()
        // 开启multipart解析
        request.setExpectMultipart(true)

        // 监听文本表单项解析完成事件
        request.formAttributeHandler { attr ->
            // 收到文本表单项就可以直接处理,不用等文件上传完成
            when(attr.key) {
                "title" -> println("收到标题:${attr.value}")
                "description" -> println("收到描述:${attr.value}")
            }
        }

        // 监听文件part上传事件
        request.uploadHandler { upload ->
            // upload为Vert.x原生HttpServerFileUpload对象,支持流式读取
            println("开始接收文件:${upload.fileName()}")

            // 每收到一块文件分片就处理,比如实时写入对象存储、计算哈希、转码等
            upload.handler { chunk ->
                println("收到文件分片,大小:${chunk.length()}")
                // 这里写你的分片处理逻辑
            }

            // 当前文件part接收完成回调
            upload.endHandler {
                println("文件${upload.fileName()} 接收完成")
            }
        }

        return Response.accepted().build()
    }
}

你提到的AsyncFile能力可以直接通过pipeTo方法实现,和流式下载体验一致:

// 直接把上传流异步写入本地文件,不需要等完整文件加载到内存
upload.pipeTo(vertx.fileSystem().openAsync("/path/to/save/file", OpenOptions().setAppend(true)))

方案2:自定义FormDataParser适配POJO映射

如果你希望保留POJO表单映射的写法,可以自定义FormDataParser实现,Quarkus支持通过CDI注册自定义解析器覆盖默认实现,不过改造成本比方案1高,适合需要统一处理多上传接口的场景:

  1. 实现org.jboss.resteasy.reactive.server.core.multipart.FormDataParser接口,重写解析逻辑,不缓存完整文件,直接把流封装到自定义的表单字段类型中
  2. 用@Produces @Priority(1)注解注册自定义解析器的Bean,优先级高于默认实现即可。

注意事项

  • 可以在application.properties中配置quarkus.http.multipart.enable-file-uploads=true确保文件上传功能开启,同时调整quarkus.http.limits.max-chunk-size适配你的分片大小需求
  • 原生Vert.x API自带响应式背压控制,只要你不强制把所有分片缓存到内存,不会出现OOM问题

内容的提问来源于stack exchange,提问作者ninja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 10:06:04