Любое обходное решение для игнорирования неожиданных элементов в 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, используя защиту сообщений и взаимную проверку сертификатов, ниже, я могу предоставить более подробную информацию.