我继承了一个以前工作正常的Web服务,直到我们必须升级运行时环境(从JBOSS / JRE6到Tomcat7 / JRE7)。除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响应中的这个(次要但关键的)更改感到困惑。
特别是,我想了解:
我能在pom.xml中发现的唯一相关更改是:
添加以下依赖项:
<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>
将cxf-rt-frontend-jaxws
依赖项从2.2.7更新为2.7.7。
将cxf-rt-transports-http
依赖项从2.2.7更新为2.7.7。
将cxf-rt-ws-security
依赖项从2.2.7更新为2.7.7。
添加以下依赖项:
<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: 罪魁祸首原来是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
工作。
我希望这可以帮助遇到类似问题的人。
答案 0 :(得分: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,或者使用自己的JAX-B,则可以。如果您愿意,您可以提供“提供者”并自己完成整个工作。
在CXF中有一个选项可以将对象传递给JAX-B,该对象决定使用哪个前缀用于什么命名空间,但我认为它不能用于强制特定命名空间被默认。您可以通过Provider和精心配置的JAX-B API调用获得所需的内容。
CXF用户邮件列表存档中有数百条消息,这些消息来自与名字命名前缀一起向上游游泳的人。
(至于tomcat死亡,那么,这是另一个问题。)