【问题标题】:What could be be injecting an extra xmlns into a SOAP response?什么可能会将额外的 xmlns 注入 SOAP 响应?
【发布时间】:2015-11-17 05:19:33
【问题描述】:

在我们不得不升级运行时环境(从 JBOSS/JRE6 到 Tomcat7/JRE7)之前,我继承了一个过去可以正常工作的 Web 服务。除了pom.xml!

之外没有任何代码更改

事实上,它仍然可以正常工作,只是许多existing 客户端无法再处理响应,因为(响应的)元素之一中现在存在一个额外的命名空间属性。

也就是说,以前(在迁移之前)该元素(在 SOAP 响应中)曾经是:

<OurResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:noNamespaceSchemaLocation="OurResponse.xsdXMLSchema-instance" 
             ourresponseVersion="M1m2v03" xmlns="">

现在是:

<v01:OurResponse acknowledgementVersion="M1m2v03" 
     xmlns:v01="http://webservice.ourdomain.com/projone/modtwo/M1m2v03">

由于没有涉及代码更改,我对 SOAP 响应中的这种(微小但关键的)更改感到困惑。

特别是,我试图理解:

  1. 构建系统的哪个部分更改了这个命名空间属性?
  2. 如何将其恢复到以前的行为?
  3. 为什么客户会因为如此微小的变化而崩溃? (即响应的内容是相同的!)

我能够在 pom.xml 中发现的唯一相关更改是:

  1. 添加以下依赖项:

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk16</artifactId>
        <version>1.46</version>
    </dependency>
    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>2.7.4</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>3.0.7.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  2. cxf-rt-frontend-jaxws 依赖项从版本 2.2.7 更新到 2.7.7。

  3. cxf-rt-transports-http 依赖项从版本 2.2.7 更新到 2.7.7。

  4. cxf-rt-ws-security 依赖项从版本 2.2.7 更新到 2.7.7。

  5. 添加以下依赖项:

    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-core</artifactId>
        <version>2.7.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-databinding-aegis</artifactId>
        <version>2.7.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-management</artifactId>
        <version>2.7.7</version>
    </dependency>
    

再次,我假设其中一个在内部处理此问题的框架(CXF?Spring?)发生了一些内部变化。如果这个假设是正确的,那么:

  1. 构建系统的哪个部分更改了这个命名空间属性?
  2. 如何将其恢复到以前的行为?
  3. 为什么客户会因为如此微小的变化而崩溃? (即响应的内容是相同的!)

更新 1: 罪魁祸首原来是 org.apache.cxf 软件包版本从 2.2.7 更改为 2.7.7。

看起来更新并不总是更好...除非有办法以编程方式强制剥离命名空间前缀的遗留行为?

更新 2: 在 Tomcat7/JRE7 上使用 CXF 2.2.7 的副作用是在发送单个 SOAP 消息后终止 Tomcat 服务器(似乎与 SSL 有关)。

像 Tomcat 这样古老的服务器可能会因为 single 流氓 .war 包而死掉这一事实非常令人不安,但由于我无法修复 Tomcat,而且我还没有找到解决隐式命名空间的编程方法前缀问题,我尝试了各种稳定的 CXF 版本,它们会在不杀死 Tomcat 的情况下表现出遗留行为。

我尝试了 2.7.1 和 2.6.10 版本,但最终只有 2.5.9 有效。

我希望这对遇到类似问题的人有所帮助。

【问题讨论】:

    标签: spring soap cxf xml-namespaces xmlbeans


    【解决方案1】:

    由于使用 xmlns 属性的更改,不允许符合标准的 XML 实现死掉。使用前缀或不使用前缀来表示相同的数据模型,这是一回事。如果您的客户端失败,您需要修复客户端。如果您的客户端对使用命名空间前缀而不是对真实数据模型非常敏感,那么 CXF 不一定是一个好的选择。

    CXF 很可能升级到了更新版本的 JAX-B,它改变了对命名空间前缀的看法。

    详细说明:Apache CXF 旨在专注于符合标准的 Web 服务。 Apache Axis 传统上填补了不太符合标准的 Web 服务的空间,很好。所以不,CXF 开发社区从不担心“前缀稳定性”。如果 XML 在形式上是正确的,那么 CXF 测试就会很高兴。

    出于这个原因以及许多其他原因,CXF 将 JAX-B Web 服务的 XML 生成委托给官方 JAX-B 参考实现。新版本的 CXF 采用新版本的 JAX-B。 JAX-B 会不时进行更改,从而重新排列命名空间前缀。

    CXF 中的 XML 生成是可插入的,因此如果您想使用较旧的 JAX-B,或者使用自己的 JAX-B,您可以。如果您愿意,您可以提供一个“提供者”并自己完成整个工作。

    CXF 中有一个选项可以将对象传递到 JAX-B 中,该选项决定将哪个前缀用于哪个命名空间,但我认为它不能用于强制默认特定命名空间。通过提供者和对 JAX-B API 的精心配置调用,您可能能够获得所需的内容。

    CXF 用户邮件列表存档包含数百条来自带有命名空间前缀的上游人的消息。

    (至于tomcat死了,那是另一个问题。)

    【讨论】:

    • 我也是这么想的。但请注意我原帖中的以下内容:“...许多现有客户端无法再处理响应...”。 IOW,这些客户都不是我们写的。因此,尽管我同意您的观点,即由于使用 xmlns 属性的更改而不允许符合标准的 XML 实现,但我必须“修复”我迁移的 Web 服务以兼容老虫子。你知道有什么程序化的方式来实现吗?
    • 创建一个 CXF 拦截器,让它看起来像你想要的样子。
    • 谢谢。我发现 this page 作为 CXF 拦截器的介绍,我一定会考虑这一点。尽管如此,我认为在迁移任何包时,无代码更改应该导致无输出更改,或者至少有一些开关或选项来实现这一点。您是否知道任何上述 Maven CXF 包中的选项来更改它,这样我就可以避免编写 CXF 拦截器?
    • 感谢您对此进行详细说明(+1 并接受)。顺便说一句,我喜欢你的maven seder blog post
    猜你喜欢
    • 1970-01-01
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多