В рамках более широкого сотрудничества мы взаимодействуем с веб-службой третьей стороной , которая предоставила нам свое описание службы .wsdl / .xsd.
.Файл wsdl описывает три типа сообщений, представляющих неисправности . Все они имеют одинаковый тип элемента .Относительная часть в файле .wsdl выглядит следующим образом:
<message name="ExceptionType1">
<part name="fault" element="customNamespace:customCommonType"/>
</message>
<message name="ExceptionType2">
<part name="fault" element="customNamespace:customCommonType"/>
</message>
<message name="ExceptionType2">
<part name="fault" element="customNamespace:customCommonType"/>
</message>
<portType name="portTypeName">
<operation name="opName">
<input [...] />
<output [...] />
<fault message="customNamespace:ExceptionType1" name="ExceptionType1"/>
<fault message="customNamespace:ExceptionType2" name="ExceptionType2"/>
<fault message="customNamespace:ExceptionType3" name="ExceptionType3"/>
</operation>
</portType>
Мы используем Axis2 1.7.9 для генерации типов данных и служебной заглушки.Мы также создали сервис Skeleton для внутренних тестов.
Для трех типов ошибок Axis2 генерирует три класса , каждый , расширяющий Exception
и споле типа CustomCommonType
(также сгенерированное Axis2 в соответствии с описанием XSD).
У нас возникают проблемы с распознаванием типа ошибок, которые получает моя заглушка, сгенерированная Axis2, по двум направлениям:
- Во время инициализации закрытый метод
populateFaults
заполняет два объекта HashMap<org.apache.axis2.client.FaultMapKey, String>
faultExceptionNameMap
и faultExceptionClassNameMap
одной записью на тип ошибки.Проблема в том, что FaultMapKey
параметризован каждый раз с QName
, который является полным квалифицированным именем customCommonType
и opName
; это приводит к тому, что каждое отображение перезаписывает предыдущее , каждая карта имеет в конце только последнее имя класса исключения в порядке вставки. Когда я выбрасываю каждое из трех исключений изСгенерированный Axis2 Skeleton, ответ, который я получаю, всегда выглядит так (ответ, полученный с помощью SoapUI):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>
This is the string that gets passed to the
constructor Exception(String),
inherited by the three custom exceptions
</faultstring>
<detail>
<customNamespace:customCommonType xmlns:customNamespace="<url>">
[contents of CustomCommonType]
</customNamespace:customCommonType>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
Код, генерирующий исключение:
ExceptionType1 t1 = new ExceptionType1("[What is in <faultstring>]");
CustomCommonType cct;
[...]
//Configure a proper cct object
[...]
t1.setCustomCommonType(cct);
throw t1;
Метод SkeletonСам принимает объект полезной нагрузки и возвращает объект ответа , сгенерированный Axis2 .Помимо некоторых обязательных xsd-определенных ограничений и некоторых средств для [де-] сериализации, эти объекты, а также CustomCommonType
, фактически действуют как DTO , то есть они не предоставляют средств дляустановить коды состояния или другие атрибуты ответа , , а также сам скелет (сгенерированный скелет содержит только пустые методы, соответствующие интерфейсу службы).Независимо от того, какой из трех типов ошибок выдается, ответное сообщение должно быть одинаковым.
На данный момент у нас нет конечной точки WS для тестов нашим партнером в этом проекте, поэтому мы не можем быть уверены в том, какой формат должен иметь их ответ (например, пользовательский soapenv.Server.X
код ошибки), и, таким образом, реализуем некоторую специальную логику, переопределяющую стандартную заглушку.
ЧтоЯ хотел бы знать: - это больше проблема фреймворка Axis2 (не направлять информацию об исключении, относящуюся к исключению, то есть имени класса), означает, что это проблема на нашей стороне, что нам придется решить эту проблему самостоятельно (изменить структуру / заново изобрести колесо самостоятельно / попросить наших партнеров включить некоторую информацию в определение commonCustomType xsd), или является определением службы несколько необычным ?
Я исследовал сам модуль spring-ws для резервного копирования и видел, что он генерирует элементы запроса, ответа и ошибки в опубликованном .wsdl на основе суффиксов в элементеопределения в файле .xsd (и инкапсулируют их в операции с произвольным именем и типами портов) ( документация ).Даже если технически это только одна реализация, а в спецификации WSDL 1.2 написано "Операция МОЖЕТ иметь ноль или более свойств сообщения об ошибке" , Подход с использованием суффикса spring-ws , похоже, усиливает представление о том, что операция должна иметь не более одного отказа .Это (неявное) предположение, похоже, лежит в основе поведения Axis2 в случае, который я только что описал.