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

Jersey/JAXB 3迁移后PUT/POST接口报SAXParseException求助

解决Jersey 3.x/Jakarta 10迁移后PUT/POST XML接口解析失败问题

针对你遇到的org.xml.sax.SAXParseException根元素前格式错误问题,给你几个实际排查方向:

1. 排查Jakarta JAXB依赖冲突

迁移到Jakarta后,必须彻底替换所有javax相关的JAXB依赖,确保项目中只存在Jakarta版本的包:

  • 移除旧的javax.xml.bind:jaxb-api、com.sun.xml.bind:jaxb-core等依赖
  • 添加正确的Jakarta版本依赖(以Maven为例):
<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>4.0.2</version> <!-- 匹配Jersey 3.1.9的兼容版本 -->
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>4.0.2</version>
    <scope>runtime</scope>
</dependency>

用mvn dependency:tree命令检查是否还有遗留的javax.jaxb相关依赖,排除冲突。

2. 验证请求的实际传输内容

别只依赖客户端声明的请求体,直接抓包或用工具查看实际发送的XML:

  • 用Postman发送请求时切换到Raw视图,确认XML开头没有多余的空白、换行或不可见字符(除了可选的UTF-8 BOM,但Tomcat 10.1应该能处理)
  • 测试极简请求体(比如<root>test</root>),排除复杂XML结构的问题
  • 检查请求头Content-Type是否为application/xml;charset=UTF-8,避免用text/xml或未指定编码的类型

3. 检查Jersey的XML解析器配置

Jersey 3.x默认使用Jakarta的MessageBodyReader,但如果有自定义配置可能干扰解析:

  • 在你的ResourceConfig实现中显式注册Jakarta的XML绑定提供者:
import jakarta.ws.rs.ApplicationPath;
import org.glassfish.jersey.jaxb.JaxbFeature;
import org.glassfish.jersey.server.ResourceConfig;

@ApplicationPath("/api")
public class MyApplication extends ResourceConfig {
    public MyApplication() {
        register(JaxbFeature.class); // 确保注册Jakarta版本的JAXB支持
        // 其他资源注册...
    }
}
  • 如果有自定义的MessageBodyReader,检查是否已将所有javax包路径替换为jakarta(比如javax.ws.rs.core→jakarta.ws.rs.core,javax.xml.bind→jakarta.xml.bind)

4. 调整Tomcat的字符编码设置

Tomcat 10.1的默认编码配置可能和Tomcat 9不同,强制统一编码:

  • 在conf/server.xml的Connector节点添加编码配置:
<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           URIEncoding="UTF-8"
           useBodyEncodingForURI="true"/>
  • 在web.xml中添加字符编码过滤器:
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>ignore</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

5. 检查自定义JAXB上下文的初始化

如果项目中自定义了JAXBContextResolver,必须切换到Jakarta API:

import jakarta.ws.rs.ext.ContextResolver;
import jakarta.ws.rs.ext.Provider;
import jakarta.xml.bind.JAXBContext;
import java.util.HashMap;
import java.util.Map;

@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {
    private final JAXBContext context;
    private final Map<Class<?>, JAXBContext> contextMap = new HashMap<>();

    public JAXBContextResolver() throws Exception {
        // 初始化你的JAXB类,确保用的是jakarta.xml.bind.JAXBContext
        context = JAXBContext.newInstance(YourEntityClass.class);
        contextMap.put(YourEntityClass.class, context);
    }

    @Override
    public JAXBContext getContext(Class<?> type) {
        return contextMap.getOrDefault(type, context);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:14:52