Maven Jersey项目WriterInterceptorExecutor报错求助(XML返回场景)
解决Jersey 2.43 + Tomcat 9中@XmlRootElement返回XML的WriterInterceptorExecutor错误
问题本质
这个严重错误是因为Jersey找不到能序列化XML实体的MessageBodyWriter,即便加了@XmlRootElement注解,核心问题在于缺少JAXB相关依赖或Jersey XML支持模块未正确引入,另外实体类的JAXB规范要求也可能没满足。
分步解决方案
1. 修正pom.xml依赖配置
确保引入Jersey的JAXB支持模块,同时统一依赖版本避免冲突。关键依赖如下:
<!-- Jersey核心Servlet容器依赖 --> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <version>2.43</version> </dependency> <!-- Jersey XML序列化支持(JAXB) --> <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-jaxb</artifactId> <version>2.43</version> </dependency> <!-- JAXB API及运行时实现(Tomcat环境下补充避免缺失) --> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>2.3.1</version> <scope>runtime</scope> </dependency>
注意:如果之前引入过jaxb-impl等旧依赖,建议替换为jaxb-runtime,避免版本冲突。
2. 检查实体类Student.java的规范
确保注解包导入正确,并且满足JAXB序列化的强制要求:
import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "student") public class Student { private int id; private String name; // JAXB序列化必须要有无参构造函数 public Student() {} // 带参构造、getter/setter方法 public Student(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
重点:无参构造函数是JAXB序列化的硬性要求,缺失会直接导致序列化失败触发错误。
3. 验证web.xml的Jersey配置
确保Servlet配置正确,指定了接口和实体类所在的包,或者自定义的ResourceConfig类:
<servlet> <servlet-name>Jersey Web App</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <!-- 方式1:直接指定扫描包 --> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>你的接口包名,你的实体类包名</param-value> </init-param> <!-- 方式2:指定自定义ResourceConfig类(二选一) --> <!-- <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>你的包名.MyApplication</param-value> </init-param> --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey Web App</servlet-name> <url-pattern>/api/*</url-pattern> </servlet-mapping>
如果用自定义ResourceConfig,可以显式注册JAXB特性确保生效:
public class MyApplication extends ResourceConfig { public MyApplication() { packages("你的接口包名"); register(JaxbFeature.class); } }
4. 请求时指定Accept头
发起GET请求时,必须在请求头中添加Accept: application/xml,明确告诉Jersey返回XML格式响应。如果浏览器默认请求HTML,Jersey找不到对应处理器也会触发错误。可以用curl测试:
curl -H "Accept: application/xml" http://localhost:8080/你的项目名/api/studs
验证流程
- 执行
mvn clean install清理并重新构建项目,确保依赖正确下载 - 重启Tomcat服务器
- 发起带
Accept: application/xml头的请求,验证是否返回正确的XML响应
内容的提问来源于stack exchange,提问作者Yash Singh
相关产品推荐
相关产品推荐

