На мой взгляд, работая с CXF лучше использовать именно 'Java first' схему объявления интерфейса. В основном потому, что манипулируя аннотациями легче получить желаемый WSDL.
Итак, процесс описания интерфейса веб сервиса предельно прост и довольно подробно описан на сайте CXF. Но встречаются мелкие моменты, которые не описаны толком, но при этом не дают спать спокойно.
Имена параметров и возвращаемых значений
Собственно говоря это не хитрость, а просто 'не приятное наблюдение' – все параметры методов пройдется проаннотировать с помощью @WebParam (если хочется получить удобочитаемый интерфейс). Так что если интерфейс объемный, то пройдется запастись терпением :)Указание главного targetNamespace для WSDL
По умолчанию targetNamespace для тега 'wsdl:definitions ' берется с имени пакета. Т.е. если SEI находится в org.test.ws то результирующий WSDL будет начинаться примерно вот так:<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="http://ws.test.org/">Есть возможность явно указать targetNamespace для всего WSDL (параметр параметр 'targetNamespace' для аннотации @WebService). И если @WebService присутствует и в SEI (интерфейсе) и в реализации (классе) (или SEI и реализация находятся в разных пакетах), то лучше проследить, чтобы значения 'targetNamespace' совпадали. Иначе в результирующем WSDL появится тег 'wsdl:import' (и некоторые неудобства, связанные с этим).
Исключения (wsdl:fault)
Довольно 'интересной' задачей оказалось корректное объявление исключений. Полное описание как это сделать присутствует только в спецификации JAX-WS. Вот пример:@WebFault public class MyException extends Exception { private MyFaultInfo faultInfo = null; public MyException(String message, MyFaultInfo faultInfo) { super(message); this.faultInfo = faultInfo; } public MyException(String message, MyFaultInfo faultInfo, Throwable cause) { super(message, cause); this.faultInfo = faultInfo; } public MyFaultInfo getFaultInfo() { return faultInfo; } } @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "my-fault-info-type", propOrder = { "description" }) @XmlRootElement(name = "my-fault-info") public class MyFaultInfo { private String description = null; public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }Что необходимо соблюсти:
- Наше исключение унаследовано от java.lang.Exception (или его потомка)
- Присутствует два обязательных конструктора (с параметрами 'String, MyFaultInfo' и 'String, MyFaultInfo, Throwable')
- Присутствует метод getFaultInfo()
- Класс-носитель дополнительной информации (в нашем случае это MyFaultInfo) мапится по всем правилам JAXB
Параметры типа Map, бинарные данные и прочие
В отличии от XFire, CXF 'не понимает' параметры типа Map, DataSource и т.д.Для преодоления этих неудобств приходится прибегать к помощи класса XmlAdapter и аннотации @XmlJavaTypeAdapter.
Комментариев нет:
Отправить комментарий