1

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

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

也就是说,以前(在迁移之前)该元素(在 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. 将依赖项从版本 2.2.7 更新cxf-rt-frontend-jaxws到 2.7.7。

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

  4. 将依赖项从版本 2.2.7 更新cxf-rt-ws-security到 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 这样古老的服务器可能会因为单个流氓 .war 包而死掉这一事实非常令人不安,但由于我无法修复 Tomcat,而且我还没有找到解决隐式命名空间前缀问题的编程方法,所以我尝试了各种稳定的 CXF 版本会在不杀死 Tomcat 的情况下表现出遗留行为。

我尝试了 2.7.1 和 2.6.10 版本,但最终只能2.5.9工作。

我希望这可以帮助遇到类似问题的人。

4

1 回答 1

2

由于使用 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,或者自己开发,都可以。如果您愿意,您可以提供一个“提供者”并自己完成整个工作。

CXF 中有一个选项可以将对象传递给 JAX-B,该选项决定将哪个前缀用于哪个命名空间,但我认为它不能用于强制默认特定命名空间。您可能能够通过提供者和对 JAX-B API 的仔细配置调用来获得您想要的东西。

CXF 用户邮件列表存档有数百条消息,这些消息来自和来自上游的具有命名空间前缀的人。

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

于 2013-10-30T20:17:39.157 回答