从Quarkus应用上传文件至Jersey 2 REST服务时出现fileMetaData为空的500错误问题
我来帮你搞定这个问题——你的Quarkus客户端和Jersey服务端的multipart参数逻辑不匹配,才导致了服务端的fileMetaData为null,进而抛出500错误。
问题根源
你的Jersey服务期望从同一个名为file的表单字段中同时获取文件流(InputStream)和对应的内容处置信息(FormDataContentDisposition),但你当前的Quarkus代码把文件名拆成了单独的fileName字段。这种情况下,服务端无法从file字段中解析出包含文件名的Content-Disposition头,自然就会导致fileMetaData为null。
解决方案
这里给你两种可行的解决方式,第二种更简洁推荐:
方案一:调整MultipartBody实体类,绑定Content-Disposition头
修改你的MultipartBody,让file字段同时携带文件流和对应的Content-Disposition头信息:
import javax.ws.rs.FormParam; import javax.ws.rs.HeaderParam; import javax.ws.rs.core.MediaType; import org.jboss.resteasy.annotations.providers.multipart.PartType; import java.io.InputStream; public class MultipartBody { @FormParam("file") @PartType(MediaType.APPLICATION_OCTET_STREAM) public InputStream file; @FormParam("file") @HeaderParam("Content-Disposition") public String contentDisposition; }
构造请求时,手动设置符合规范的Content-Disposition头:
// 示例:读取本地文件 InputStream fileStream = new FileInputStream(new File("/path/to/your/target-file.txt")); String fileName = "target-file.txt"; MultipartBody body = new MultipartBody(); body.file = fileStream; // 构造包含文件名的Content-Disposition头 body.contentDisposition = String.format("form-data; name=\"file\"; filename=\"%s\"", fileName); // 调用服务 String response = multipartService.sendMultipartData(body);
方案二:使用MultipartFormDataOutput直接构建请求(推荐)
这种方式更简洁,RestEasy的MultipartFormDataOutput会自动帮你处理Content-Disposition头的设置:
首先修改你的MultipartService接口:
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput; import javax.ws.rs.POST; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; @RegisterRestClient public interface MultipartService { @POST @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_PLAIN) String sendMultipartData(MultipartFormDataOutput output); }
然后在调用时构建请求体:
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput; import java.io.File; import java.io.FileInputStream; // 准备待上传的文件 File targetFile = new File("/path/to/your/target-file.txt"); String fileName = targetFile.getName(); MultipartFormDataOutput output = new MultipartFormDataOutput(); // addFormData方法会自动添加包含filename的Content-Disposition头 output.addFormData("file", new FileInputStream(targetFile), MediaType.APPLICATION_OCTET_STREAM, fileName); // 调用服务 String response = multipartService.sendMultipartData(output);
为什么这样有效?
Jersey的@FormDataParam("file") FormDataContentDisposition是从请求中file字段的Content-Disposition头解析而来的。上面两种方案都确保了这个头被正确设置,服务端就能正常解析出fileMetaData,不会再返回null了。
内容的提问来源于stack exchange,提问作者Harsha D G

