使用Jersey调用REST接口遇FormDataMultiPart消息体写入器缺失问题
问题分析与解决方案
核心问题
从堆栈信息能看到,实际运行时使用的是Apache CXF的JAX-RS客户端实现,而非你代码里调用的Jersey客户端。这是依赖冲突导致的:你同时引入了Jersey 1.x(com.sun.jersey)、Jersey 2.x(org.glassfish.jersey),且项目中可能间接引入了CXF的JAX-RS依赖,导致客户端被CXF接管,而CXF没有配置Jersey的Multipart处理组件。
分步解决
1. 清理依赖冲突
- 移除
com.sun.jersey:jersey-core依赖:Jersey 2.x是1.x的完全替代版本,两者不能共存,会引发类加载冲突。 - 检查项目依赖树,排除所有Apache CXF的JAX-RS客户端相关依赖(比如
cxf-rt-frontend-jaxrs),确保只有Jersey 2.x的客户端依赖生效。 - 保留
jersey-media-multipart依赖,无需手动排除mimepull,Jersey 2.x会自动适配兼容版本。
清理后的核心依赖示例:
<dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-client</artifactId> <version>2.34</version> </dependency> <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-multipart</artifactId> <version>2.34</version> </dependency>
2. 正确注册MultipartFeature到Jersey Client
创建Client时必须显式注册MultipartFeature,否则Jersey无法处理FormDataMultiPart类型的请求体:
// 注册MultipartFeature后再创建Client实例 Client client = ClientBuilder.newClient().register(MultipartFeature.class); FormDataMultiPart formData = new FormDataMultiPart(); formData.field("options", "docUpload"); formData.bodyPart(new FileDataBodyPart("file", file)); try { Response response = client.target(TARGET_END_POINT + SUBMIT_DOCUMENT) .request() // 无需指定request的MediaType,Multipart请求由Entity处理 .post(Entity.entity(formData, formData.getMediaType())); // 处理响应逻辑... } finally { // 关闭资源避免内存泄漏 formData.close(); client.close(); }
3. 验证客户端实现
运行时可以打印Client的类名,确认使用的是Jersey的实现:
System.out.println(client.getClass().getName()); // 正常输出应为org.glassfish.jersey.client.JerseyClient
如果输出包含cxf字样,说明仍有CXF依赖未排除,需继续清理依赖树。
内容的提问来源于stack exchange,提问作者Srikanth R
相关产品推荐
相关产品推荐

