在 Apache Axis 1.4 中忽略意外元素的任何解决方法?

2022-09-02 22:34:08

这个问题在2012年Apache Axis 2的“Apache AXIS在解析时忽略/跳过其他元素”之前被问到。安讯士 1.4 尚无解决方法吗?

问题定义

例如;

1-我们在开发时的 wsdl 中有一个 soap 响应定义('ResponseGetCustomerInfo'):

...
  <xs:element name="ResponseGetCustomerInfo">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ns1:CustomerID"/>
        <xs:element ref="ns1:CustomerUsername"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="CustomerID" type="xs:integer"/>
  <xs:element name="CustomerUsername" type="xs:string"/>
...

2-很高兴看到当我们得到这样的响应是可解析的:

<?xml version="1.0" encoding="utf-8" ?> 
<soap:Envelope 
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <ResponseGetCustomerInfo xmlns="http://tempUri.org/">
            <CustomerID>1</CustomerID>
            <CustomerUsername>raki</CustomerUsername>
        </ResponseGetCustomerInfo>
    </soap:Body>
</soap:Envelope>

3-一段时间后,我们的服务提供商更改了服务响应,并在响应中添加了新的输出字段,我们不知道何时或为什么;

<?xml version="1.0" encoding="utf-8" ?> 
<soap:Envelope 
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <ResponseGetCustomerInfo xmlns="http://tempUri.org/">
            <CustomerID>1</CustomerID>
            <CustomerUsername>raki</CustomerUsername>
            <CustomerName>Raki</CustomerName>
            <CustomerSurname>Bandao</CustomerSurname>
        </ResponseGetCustomerInfo>
    </soap:Body>
</soap:Envelope>

4-新响应理论上与旧版本兼容,因为没有字段既没有删除也没有更改。但安讯士无法解析响应:

"SAXException: Invalid Element ... "

我不想更新 wsdl 并再次重新生成 Web 服务客户端。那么,有没有办法跳过响应中的“意外[新添加]元素”?或任何解决方法?

我正在尝试许多方法,但尚未找到任何解决方案。


答案 1

由于编写这些服务的不良供应商,我们总是经历这个地狱。

所以,不幸的是,使用WSDL2JAVA的参数是没有办法的,但是有一个解决方法,你将至少重新生成一次存根:

  1. 替换为 。这允许元素以任何顺序返回,并有助于修复许多情况,以及生成的存根代码,这使得步骤更容易xs:sequencexs:all
  2. 抱歉,但是对于每个响应 Bean,您从生成的代码(例如 ResponseGetCustomerInfo.java)进入其类,而不是这样:
while(!reader.isStartElement() && !reader.isEndElement())
   reader.next();

if(reader.isStartElement())
// A start element we are not expecting indicates a trailing invalid
// property
throw new org.apache.axis2.databinding.ADBException("Unexpected subelement " + reader.getLocalName());

有这个:

while(!reader.isStartElement() && !reader.isEndElement())
   reader.next();

// if(reader.isStartElement())
// A start element we are not expecting indicates a trailing invalid
// property

// The below is commented, to prevent unexpected result parameters from causing an exception
// (As well as the condition above is removed)
//  throw new org.apache.axis2.databinding.ADBException("Unexpected subelement " + reader.getLocalName());

它经过测试,至少比没有解决方案更好。


答案 2

没有使用过安讯士 1.4,而是在快速浏览了文档之后。

可以向代码中添加处理程序。您甚至应该能够执行此操作而不必重新编译它,这是一个问题。处理程序包装基础 Web 服务,在调用服务之前和返回服务之后调用它。它有点像Servlet过滤器,但对于Web服务。

处理程序在发送 SOAP 正文进行处理之前具有对 SOAP 正文的完全访问权限。因此,您可以利用此机会删除您不喜欢的元素。

稍微挖掘一下,你会发现你最终会得到一个DOM元素来代表你的SOAP体,所以你可以玩原始的DOM游戏来添加/删除节点等,并在处理程序中将其设置回去。

您的服务永远不会在编辑 SOAP 主体中看到新节点。

总而言之,您甚至可以使用Servlet过滤器来执行此操作。


推荐