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

Jersey 3.0.2/Jetty 11.0.0 REST服务无法生成XML响应问题求助

问题背景

使用技术栈为Open JDK 15、Jersey 3.0.2、Jetty 11.0.0开发REST Web服务时,返回XML响应出现故障,JSON响应功能正常。无论选择哪款Xml Provider,Jersey最终都会选中不兼容XML的Provider甚至找不到可用Provider,ResourceConfig配置未被服务器正常生效。

现有配置

ResourceConfig 配置代码:

ResourceConfig resourceConfig = new ResourceConfig(
        EchoControllerXml.class
).packages("lu.isd.jetty.model.echo")
        .register(MoxyXmlFeature.class);

服务创建代码:

Server server = JettyHttpContainerFactory.createServer(appUri, resourceConfig, false);
异常表现

调用curl http://localhost:10020/xml/bonjour时无任何返回,抛出异常如下:

java.io.IOException: Unconsumed content
    at org.eclipse.jetty.server.HttpInput.consumeAll(HttpInput.java:133)
    at org.eclipse.jetty.server.HttpConnection.onCompleted(HttpConnection.java:432)
    at org.eclipse.jetty.server.HttpChannel.onCompleted(HttpChannel.java:859)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:384)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:289)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:324)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
    at org.eclipse.jetty.io.SocketChannelEndPoint$1.run(SocketChannelEndPoint.java:106)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:790)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:912)
    at java.base/java.lang.Thread.run(Thread.java:832)
根因分析
  1. Jersey 3.x属于Jakarta EE 9+版本,所有包命名从javax.*迁移到了jakarta.*,如果使用旧的javax.xml.bind相关依赖,会导致XML Provider不兼容无法被识别。
  2. JettyHttpContainerFactory.createServer第三个参数设为false时,没有手动调用server.start()启动服务,导致ResourceConfig的注册逻辑没有被Jetty容器加载生效,Jersey扫描不到注册的XML Provider,返回序列化失败,Jetty检测到未消费的响应内容就抛出了Unconsumed content异常。
修复步骤
  • 检查Maven依赖,确保所有XML绑定相关依赖都是jakarta版本,排除旧的javax版本依赖:
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-moxy</artifactId>
    <version>3.0.2</version>
</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>
  • 修改服务启动逻辑,要么把createServer的第三个参数改成true让工厂自动启动服务,要么手动调用server.start():
// 方案1:自动启动
Server server = JettyHttpContainerFactory.createServer(appUri, resourceConfig, true);

// 方案2:手动启动
Server server = JettyHttpContainerFactory.createServer(appUri, resourceConfig, false);
server.start();
server.join();
  • 给返回的XML实体类加上@XmlRootElement注解,注意这个注解要导入jakarta.xml.bind.annotation.XmlRootElement,不要导入javax的同名类。
  • 在Controller的接口方法上显式指定produces类型为MediaType.APPLICATION_XML:
@GET
@Path("/{msg}")
@Produces(MediaType.APPLICATION_XML)
public EchoResponse echo(@PathParam("msg") String msg) {
    return new EchoResponse(msg);
}

内容的提问来源于stack exchange,提问作者the duck

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:54:03