使用@FormDataParam注解导致multipart/form-data请求返回400 Bad Request(Jersey 3.1.10、Java 17、Tomcat 10)
使用@FormDataParam注解导致multipart/form-data请求返回400 Bad Request(Jersey 3.1.10、Java 17、Tomcat 10)
嘿,作为资深API开发者碰到这种新端点的400问题确实闹心,我来帮你捋捋Jersey 3.x环境下最常见的几个坑!
优先级最高的排查点:没配置Multipart支持
Jersey 3.x之后,multipart/form-data的处理不再是默认内置的了,这是绝大多数人踩的第一个坑:
- 添加依赖包
如果用Maven,在pom.xml里补上:
Gradle的话就加:<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-multipart</artifactId> <version>3.1.10</version> </dependency>implementation 'org.glassfish.jersey.media:jersey-media-multipart:3.1.10' - 注册MultipartFeature
要么在你的Application配置类里注册:
用web.xml配置的话,就给Jersey Servlet加初始化参数:@ApplicationPath("/") public class MyApiConfig extends ResourceConfig { public MyApiConfig() { packages("com.your.resource.package"); // 替换成你的接口所在包 register(org.glassfish.jersey.media.multipart.MultipartFeature.class); } }<servlet> <servlet-name>JerseyServlet</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value>org.glassfish.jersey.media.multipart.MultipartFeature</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
其次检查请求参数的匹配度
- 确认前端/测试工具(比如Postman)里的form-data参数名,和
@FormDataParam("file")里的"file"完全一致——大小写是敏感的!比如前端传的是"File"或者"upload_file",Jersey会找不到参数直接返回400。 - 确保请求里确实携带了这个
file参数,空请求或者漏传参数也会触发400。
然后验证请求的Content-Type
一定要确保请求头的Content-Type是multipart/form-data; boundary=xxxxxx(xxxxxx是自动生成的边界字符串)。有些工具可能误设成application/x-www-form-urlencoded,或者没带boundary,这会让Jersey无法解析请求体,直接报错。
别忘排查Tomcat的上传大小限制
Tomcat 10默认对上传文件的大小有限制,如果测试文件过大也会返回400:
- 修改Tomcat的
conf/web.xml,添加文件上传过滤器:<filter> <filter-name>fileUploadFilter</filter-name> <filter-class>org.apache.tomcat.util.http.fileupload.servlet.FileUploadFilter</filter-class> <init-param> <param-name>maxFileSize</param-name> <param-value>104857600</param-value> <!-- 100MB,按需调整 --> </init-param> <init-param> <param-name>maxRequestSize</param-name> <param-value>104857600</param-value> </init-param> </filter> <filter-mapping> <filter-name>fileUploadFilter</filter-name> <url-pattern>/v1/upload</url-pattern> </filter-mapping> - 或者修改
conf/server.xml里的Connector,把maxPostSize设为-1表示不限制:<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" maxPostSize="-1" redirectPort="8443"/>
可选优化:完善方法参数
可以把FormDataContentDisposition也注入进来,既能拿到文件名等信息,还能避免一些注入异常:
@POST @Path("/v1/upload") @Consumes(MediaType.MULTIPART_FORM_DATA) public Response upload( @FormDataParam("file") InputStream file, @FormDataParam("file") FormDataContentDisposition fileDisposition ) { String fileName = fileDisposition.getFileName(); // 这里写文件处理逻辑,比如保存到磁盘 return Response.ok("Received file: " + fileName).build(); }
先从Multipart的依赖和注册开始排查,这是90%以上的人碰到这个问题的根源!如果还不行,再依次检查参数名、请求头和Tomcat限制。
备注:内容来源于stack exchange,提问作者Brien Halstead




