JAX-RS返回application/xml时报MessageBodyWriter未找到错误
JAX-RS返回XML序列化报错修复方案
MessageBodyWriter not found for media type=application/xml, type=class java.util.ArrayList报错由三类配置冲突导致,按以下步骤逐一修复即可:
1. 修复JAXB注解与依赖的版本冲突
当前配置存在严重的API混用问题:
- Tomcat 10、Jersey 3.x全遵循Jakarta EE规范,所有JAXB注解必须使用
jakarta.xml.bind.*包下的类,Model类里导入的javax.xml.bind.annotation.XmlRootElement属于旧Java EE规范,和当前运行环境完全不兼容 - pom里同时引入了javax.activation 1.1、JAXB 2.3、JAXB 4.0多套跨大版本的序列化组件,类加载冲突会直接导致XML序列化器无法注册
- 使用的Java 1.8最高仅支持Jakarta XML Bind 3.0版本,引入的JAXB 4.0要求Java 11+运行环境,会直接触发类版本错误
修复操作:
- 把Model类中
import javax.xml.bind.annotation.XmlRootElement;替换为import jakarta.xml.bind.annotation.XmlRootElement;,所有JAXB注解统一使用jakarta包下的类 - 删除pom中dependencyManagement节点下的javax.activation、2.3版本jaxb-runtime两个旧依赖
- 将jakarta.xml.bind-api、jaxb-impl的版本统一降到3.0.x区间,适配Java 8运行环境,替换旧的javax.activation为jakarta.activation-api 2.0.1版本
2. 统一Jersey组件版本
当前pom中jersey-bom指定版本为3.1.0-M2(里程碑不稳定版),但jersey-media-jaxb单独写死3.0.2版本,跨版本的Jersey组件会导致自动注册的XML序列化MessageBodyWriter失效。
修复操作:
- 把jersey.version从3.1.0-M2改为3.0.2正式版,适配Tomcat 10 + Java 8环境
- 删除jersey-media-jaxb依赖上单独声明的version标签,交给jersey-bom统一管理所有Jersey组件版本,避免版本不一致
- 给jakarta.servlet-api依赖添加
<scope>provided</scope>配置,避免打包时把Tomcat自带的servlet包重复打入war包引发冲突
3. 修复后可直接复用的核心配置
修正后的pom核心片段
<properties> <jersey.version>3.0.2</jersey.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.glassfish.jersey</groupId> <artifactId>jersey-bom</artifactId> <version>${jersey.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>5.0.0</version> <scope>provided</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet-core</artifactId> </dependency> <dependency> <groupId>org.glassfish.jersey.inject</groupId> <artifactId>jersey-hk2</artifactId> </dependency> <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-jaxb</artifactId> </dependency> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>3.0.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>jakarta.activation</groupId> <artifactId>jakarta.activation-api</artifactId> <version>2.0.1</version> </dependency> </dependencies>
修正后的Model类注解导入
package org.surender.model; // 统一使用jakarta包下的JAXB注解,禁止混用javax包的旧注解 import jakarta.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "Surender") public class MessagesModel { @XmlElement(name = "Message ID") public int messageId; public String messageTxt; public String messageLike; public String messageComment; // 原有构造方法、getter、setter代码无需改动 public MessagesModel(int messageId, String messageTxt, String messageLike, String messageComment) { super(); System.out.println("Objects getting created"); this.messageId = messageId; this.messageTxt = messageTxt; this.messageLike = messageLike; this.messageComment = messageComment; } public MessagesModel() {} public int getMessageId() { return messageId; } public void setMessageId(int messageId) { this.messageId = messageId; } public String getMessageTxt() { return messageTxt; } public void setMessageTxt(String messageTxt) { this.messageTxt = messageTxt; } public String getMessageLike() { return messageLike; } public void setMessageLike(String messageLike) { this.messageLike = messageLike; } public String getMessageComment() { return messageComment; } public void setMessageComment(String messageComment) { this.messageComment = messageComment; } }
当前Resource类中用
GenericEntity包装List返回值的写法是正确的,修复完依赖和注解后无需修改这部分代码,执行mvn clean package重新打包部署到Tomcat 10即可正常返回XML响应。
内容的提问来源于stack exchange,提问作者Surender
相关产品推荐
相关产品推荐

