You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

验证流程

  1. 执行mvn clean install清理并重新构建项目,确保依赖正确下载
  2. 重启Tomcat服务器
  3. 发起带Accept: application/xml头的请求,验证是否返回正确的XML响应

内容的提问来源于stack exchange,提问作者Yash Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 02:16:00