Любое обходное решение для игнорирования неожиданных элементов в Apache Axis 1.4?

Проблема была задана перед "Apache AXIS Ignore/Пропустить дополнительный элемент при разборе" в 2012 году для Apache Axis 2. Нет ли еще обходного пути для Axis 1.4?

Определение проблемы

Например:

1 - У нас есть определение ответа на мыло ( "ResponseGetCustomerInfo" ) в нашем wsdl при разработке [с Axis 1.4]:

...
  <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 - Новый ответ, теоретически совместимый со старой версией, поскольку ни одно поле не удалено и не изменено. Но Axis не может разобрать ответ:

"SAXException: Invalid Element ... "

Я не хочу обновлять wsdl и снова восстанавливать клиент веб-сервиса. Итак, есть ли способ пропустить "Неожиданные [вновь добавленные] элементы" в ответе? или любой обходной путь?

Я пытаюсь много способов, но пока не нашел решения.

Ответы

Ответ 1

Мы всегда переживаем этот ад из-за того, что плохие продавцы пишут эти службы.

Таким образом, к сожалению, нет возможности использовать параметры для WSDL2JAVA, НО есть обходной путь, вы должны регенерировать заглушки хотя бы один раз:

  • Замените xs:sequence на xs:all. Это позволяет возвращать элементы в любом порядке и помогает исправить множество случаев, а также сгенерированный код заглушки, что облегчает выполнение шага.
  • Извините, но вы за каждый ответ 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

Не использовал Axis 1.4, но быстро взглянул на документы.

Вы можете добавить обработчик к вашему коду. Вы должны быть в состоянии даже сделать это, не перекомпилируя его, это проблема. Обработчик обертывает базовую веб-службу, она вызывается перед вызовом службы и после ее возврата. Это похоже на сервлет-фильтр, но для веб-служб.

Обработчик имеет полный доступ к телу SOAP, прежде чем он будет отправлен вперед для обработки. Таким образом, вы можете использовать это как возможность удалить элементы, которые вам не нравятся.

Копайте немного, и вы обнаружите, что в конечном итоге вы получите элемент DOM, который представляет ваше тело SOAP, поэтому вы можете играть в примитивные игры DOM, чтобы добавлять/удалять узлы и т.д., и устанавливать их обратно в обработчик.

Ваш сервис никогда не увидит новые узлы в теле редактирования SOAP.

Все, что было сказано, вы, возможно, сможете это сделать и с помощью сервлет-фильтра.

Ответ 3

Я хочу поделиться своим опытом с написанием Java-клиента с сервисом .NET WCF, безопасным общением через Интернет. Сначала мы попытались использовать библиотеку Axis 2 и имели ошибки, генерирующие Java-клиентский класс из WSDL, когда служба использовала режим Message Message. Затем мы попробовали библиотеку Metro с интегрированной средой NetBeans. У него также были некоторые проблемы, поскольку версия Metro, поставляемая с NetBeans, имела ошибку. После обновления до последнего Metro 2.3 в то время, октябрь 2014 года, мы смогли создать Java-клиент, который работает без проблем.

Ключевой частью получения успешного вызова веб-службы с Java была настройка клиентских и серверных сертификатов как на Java, так и на .Net-клиента. Вот статья, в которой объясняются этапы. http://nosuchblogger.com/post/216/wcf-message-security-with-a-java-client

Если кто-то заинтересован в более подробной информации, используя библиотеку Metro, используя защиту сообщений и взаимную проверку сертификатов, ниже, я могу предоставить более подробную информацию.