Jersey注册Multipart实现文件上传报错:未找到消息体读取器
解决Jersey中multipart/form-data上传的Message Body Reader错误
你遇到的这个错误核心原因是MultiPartFeature没有正确注册,再加上几个版本和代码结构的小问题,咱们一步步来修正:
1. 修正Maven依赖版本不一致问题
你当前的jersey-media-multipart版本是2.2,而其他Jersey依赖都是2.22.2,版本不匹配会导致类加载和功能兼容问题。把multipart依赖的版本改成和其他一致的:
<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-multipart</artifactId> <version>2.22.2</version> </dependency>
另外,jaxrs-ri这个依赖可以去掉,因为你已经单独引入了需要的Jersey模块,避免依赖冲突。
2. 修正应用配置类(WinkApplication)
你的WinkApplication里错误地把FormDataContentDisposition.class加入了注册列表,这个类是用来接收文件元数据的参数类型,不是需要注册的Feature或资源类。只需要保留MultiPartFeature和你的资源类:
import com.ibm.sampleapp.rest.ConversationWS; import java.util.HashSet; import java.util.Set; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; import org.glassfish.jersey.media.multipart.MultiPartFeature; @ApplicationPath("/api") public class WinkApplication extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<>(); // 注册MultiPartFeature,这是处理multipart请求的核心 classes.add(MultiPartFeature.class); // 注册你的REST资源类 classes.add(RESTws.class); return classes; } }
3. 修正REST资源类(RESTws)
你的RESTws类错误地继承了ResourceConfig,ResourceConfig是用来配置Jersey应用的类,而你的资源类(处理请求的类)不需要继承它。另外,方法里创建ResourceConfig并注册Feature的代码完全多余,直接删掉即可:
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataParam; @Path("") public class RESTws { // 去掉extends ResourceConfig @POST @Path("/upload") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_PLAIN) public Response uploadFile( @FormDataParam("file") InputStream uploadedInputStream, @FormDataParam("file") FormDataContentDisposition fileMetaData) throws Exception { String filename = fileMetaData.getFileName(); String uploadedFileLocation = "C:\\$User\\Doc\\" + filename; try { saveFile(uploadedInputStream, uploadedFileLocation); } catch(Exception e){ return Response.status(400).entity(e.getMessage()).build(); // 改成e.getMessage()返回更友好的错误信息 } String output = "File uploaded to: " + uploadedFileLocation; System.out.println("File uploaded.."); return Response.status(200).entity(output).build(); } // 将上传的文件保存到服务器指定位置 private void saveFile(InputStream uploadedInputStream, String serverLocation) { try (OutputStream outputStream = new FileOutputStream(new File(serverLocation))) { // 使用try-with-resources自动关闭流,避免资源泄漏 int read = 0; byte[] bytes = new byte[1024]; while ((read = uploadedInputStream.read(bytes)) != -1) { outputStream.write(bytes, 0, read); } } catch (IOException e) { e.printStackTrace(); } } }
4. 验证前端页面
你的前端HTML页面路径配置看起来没问题,确保提交的action路径/api/upload和应用配置一致,服务器端口号也和你启动的服务匹配。
做完这些修改后,重新构建并启动应用,再尝试上传文件,应该就能正常工作了。
内容的提问来源于stack exchange,提问作者HCF
相关产品推荐
相关产品推荐

