На мой взгляд, работая с 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.
Комментариев нет:
Отправить комментарий