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

Apache CXF 3.2.2添加WS-Security UsernameToken遇jaxws-rt依赖DOM异常

解决Apache CXF加WS-Security时与jaxws-rt依赖冲突的WRONG_DOCUMENT异常

嘿,这个问题我之前也碰到过!本质上是JAX-WS参考实现(com.sun.xml.ws:jaxws-rt)和Apache CXF作为两套独立的JAX-WS实现,在DOM文档处理上产生了冲突。当两个库同时存在时,CXF的WSS4JOutInterceptor在给SOAP头加UsernameToken的时候,会尝试把节点从JAX-WS RI创建的DOM文档里移到CXF管理的文档中,这就触发了org.w3c.dom.DOMException: WRONG_DOCUMENT错误——毕竟DOM规则里不允许跨文档操作节点嘛。

下面给你几个可行的解决方案,按推荐程度排序:

方案1:直接移除jaxws-rt依赖(首推)

既然你说移除这个依赖后交互完全正常,说明你的项目其实根本不需要JAX-WS RI的功能,完全可以用CXF来搞定所有JAX-WS相关的需求。直接把pom.xml里这段依赖删掉就行:

<dependency>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-rt</artifactId>
    <version>2.3.0</version>
</dependency>

CXF 3.2.2本身就完整实现了JAX-WS规范,WS-Security的UsernameToken功能也完全覆盖,没必要留着冲突的依赖。

方案2:给jaxws-rt排除冲突的DOM依赖

如果你的项目确实离不开jaxws-rt(比如有部分老代码依赖它的特定功能),那可以通过Maven的依赖排除,强制让两个库共用一套DOM处理组件。在jaxws-rt的依赖里加上排除规则:

<dependency>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-rt</artifactId>
    <version>2.3.0</version>
    <exclusions>
        <!-- 排除jaxws-rt自带的DOM和JAXB相关依赖,用CXF的版本 -->
        <exclusion>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
        </exclusion>
        <!-- 排除SOAP消息处理的冲突依赖 -->
        <exclusion>
            <groupId>com.sun.xml.messaging.saaj</groupId>
            <artifactId>saaj-impl</artifactId>
        </exclusion>
    </exclusions>
</dependency>

这样做能保证整个项目都用CXF的DOM处理上下文,就不会出现跨文档节点操作的问题了。

方案3:强制CXF使用自己的DOM解析工厂

如果上面两个方案都不生效,那可以手动指定CXF用自己的DOM解析器,避免和jaxws-rt的解析器打架。在你的CXF客户端或服务端配置代码里加这段:

// 获取CXF客户端的配置实例
Client client = ClientProxy.getClient(yourWebServicePort);
Endpoint cxfEndpoint = client.getEndpoint();

// 设置强制使用CXF依赖的Xerces解析器
Map<String, Object> properties = new HashMap<>();
properties.put("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
properties.put("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
cxfEndpoint.getProperties().putAll(properties);

要是用Spring整合CXF的话,也可以在<jaxws:client>或者<jaxws:endpoint>标签里通过properties属性来配置这些参数。

小提示

  • 可以跑一下mvn dependency:tree命令,看看完整的依赖树,说不定能发现一些隐藏的冲突依赖。
  • 排除依赖的时候,不用一下子全加,也可以先排除一两个核心的,比如saaj-impl,看看能不能解决问题,逐步调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:09:14