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

Quarkus RestClient转发多文件上传异常:接收端文件数为0

问题:Quarkus RestClient转发多文件上传时接收端无法识别文件

我正在开发基于Quarkus的服务,该服务接收多文件上传后通过RestClient转发至另一Quarkus服务。目前遇到的问题是:文件可成功上传至初始服务,但接收端日志显示文件数始终为0;直接通过Postman上传至接收端时服务可正常处理。

发送端服务代码细节

端点代码

@POST
@Path("/uploadFiles")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces("application/json")
public Response uploadFiles(@RestForm("files") List<FileUpload> fileUploads) {
    log.info("Number of files uploaded: " + fileUploads.size());  // 正确记录上传文件数
    String restClientResponse = myService.uploadFiles(fileUploads);
    return Response.ok(restClientResponse).build();
}

服务方法

public String uploadFiles(List<FileUpload> fileUploads) {
    MultipartFormDataOutput multipartFormDataOutput = new MultipartFormDataOutput();

    for (FileUpload fileUpload : fileUploads) {
        File file = fileUpload.uploadedFile().toFile();  // 获取实际文件对象
        multipartFormDataOutput.addFormData("files", file, MediaType.APPLICATION_OCTET_STREAM_TYPE, file.getName());
    }

    Response response = externalClient.uploadFiles(multipartFormDataOutput);

    if (response.getStatus() != 200) {
        throw new RuntimeException("Failed to upload files. Status: " + response.getStatus());
    }

    return response.readEntity(String.class);
}

RestClient定义

@POST
@Path("/uploadFiles")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
Response uploadFiles(@MultipartForm MultipartFormDataOutput data);

接收端服务代码细节

端点代码

@POST
@Path("/uploadFiles")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces("application/json")
public Response uploadFiles(@RestForm("files") List<FileUpload> fileUploads) {
    log.info("Number of files uploaded: " + fileUploads.size());  // 通过RestClient转发时始终记录0

    for (FileUpload fileUpload : fileUploads) {
        String fileName = fileUpload.fileName();
    }

    return Response.ok("Files uploaded successfully").build();
}

问题现象

  • 直接通过Postman上传至接收端,服务可正确记录文件数并处理;
  • 通过发送端RestClient转发时,接收端日志显示文件数为0,无法正常处理。

推测多部分表单数据未被正确构造或转发,请问遗漏了什么?如何确保通过RestClient转发时,文件及文件名等元数据能被接收端正确处理?


解决方案

问题根源

手动构造MultipartFormDataOutput时,元数据传递不完整(如文件名绑定逻辑错误),或Quarkus RestClient对手动构造的多部分表单解析逻辑与Postman的标准请求存在差异,导致接收端无法将其识别为List<FileUpload>。

方法一:简化RestClient调用(推荐)

让Quarkus自动处理多部分表单的构造,避免手动实现出错:

  1. 修改发送端RestClient定义:
@POST
@Path("/uploadFiles")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
Response uploadFiles(@RestForm("files") List<FileUpload> fileUploads);
  1. 简化发送端服务方法:
public String uploadFiles(List<FileUpload> fileUploads) {
    Response response = externalClient.uploadFiles(fileUploads);

    if (response.getStatus() != 200) {
        throw new RuntimeException("Failed to upload files. Status: " + response.getStatus());
    }

    return response.readEntity(String.class);
}

这种方式直接将接收的FileUpload列表传递给RestClient,由Quarkus框架负责生成符合标准的多部分表单请求,确保元数据完整传递。

方法二:正确手动构造MultipartFormDataOutput

如果必须手动构造多部分表单,需确保文件元数据完整传递,同时使用InputStream避免文件IO问题:

修改发送端服务方法:

public String uploadFiles(List<FileUpload> fileUploads) {
    MultipartFormDataOutput multipartFormDataOutput = new MultipartFormDataOutput();

    for (FileUpload fileUpload : fileUploads) {
        try (InputStream inputStream = Files.newInputStream(fileUpload.uploadedFile())) {
            multipartFormDataOutput.addFormData(
                "files",
                inputStream,
                MediaType.APPLICATION_OCTET_STREAM_TYPE,
                fileUpload.fileName()
            );
        } catch (IOException e) {
            throw new RuntimeException("Failed to read uploaded file", e);
        }
    }

    Response response = externalClient.uploadFiles(multipartFormDataOutput);

    if (response.getStatus() != 200) {
        throw new RuntimeException("Failed to upload files. Status: " + response.getStatus());
    }

    return response.readEntity(String.class);
}

此方式通过InputStream读取文件内容,同时明确传递文件名,确保接收端能正确解析每个文件部分。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:58:10