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自动处理多部分表单的构造,避免手动实现出错:
- 修改发送端RestClient定义:
@POST @Path("/uploadFiles") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) Response uploadFiles(@RestForm("files") List<FileUpload> fileUploads);
- 简化发送端服务方法:
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
相关产品推荐
相关产品推荐

