Включение адресации WS-Addressing в SOAP java веб-сервисе
Добавление адресации в SOAP java веб сервис. Использование аннотации @Addressing.
Используемые технологии и библиотеки
- Apache CXF 3.1.6
- Spring MVC 4.3.0.Release
1. Описание задачи
Добавить поддержку адресации в SOAP веб-сервис.
2. Структура проекта
Серверная часть ничем не отличается от прошлого проекта — Валидация данных веб-сервиса на стороне сервера с помощью reflection. Так же в этой статье описывается клиентская часть, в которой были автоматически сгенерированы классы на основе wsdl и написан простой код подключения к веб-сервису. Структура клиентской части выглядит следующим образом:
3. Addressing
На стороне сервера была добавлена только одна строчка с указанием аннотации @Addressing. У этой аннотации есть существуют различные параметры (enabled, required, responses).
1 2 3 4 5 6 7 8 |
/** * Created for JavaStudy.ru on 10.06.2016. */ @WebService(endpointInterface = "ru.javastudy.ws.soap.WebserviceSEI", serviceName = "HelloSoap") @Addressing() public class HelloSoap implements WebserviceSEI { .... |
Вот таким простым образом можно включить поддержку адресации на стороне сервера. В данном случае она не является обязательным требованием (по умолчанию required = false).
В результате добавления аннотации у нас изменится wsdl описание нашего веб-сервиса.
1 2 3 4 |
<wsdl:binding name="HelloSoapSoapBinding" type="tns:WebserviceSEI"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <strong><wsaw:UsingAddressing xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" wsdl:required="false"/></strong> <wsp:PolicyReference URI="#HelloSoapSoapBinding_WSAM_Addressing_Policy"/> |
Добавился тег <wsaw:UsingAddressing .., а так же тег <wsam:Addressing… .
Полное описание:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
This XML file does not appear to have any style information associated with it. The document tree is shown below. <wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:tns="http://soap.ws.javastudy.ru/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="HelloSoap" targetNamespace="http://soap.ws.javastudy.ru/"> <wsdl:types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://soap.ws.javastudy.ru/" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://soap.ws.javastudy.ru/"> <xs:element name="createGoods" type="tns:createGoods"/> <xs:element name="createGoodsResponse" type="tns:createGoodsResponse"/> <xs:element name="exceptionTest" type="tns:exceptionTest"/> <xs:element name="exceptionTestResponse" type="tns:exceptionTestResponse"/> <xs:element name="getGoods" type="tns:getGoods"/> <xs:element name="getGoodsResponse" type="tns:getGoodsResponse"/> <xs:element name="goods" type="tns:goods"/> <xs:element name="sayHelloTo" type="tns:sayHelloTo"/> <xs:element name="sayHelloToResponse" type="tns:sayHelloToResponse"/> <xs:element name="testService" type="tns:testService"/> <xs:element name="testServiceResponse" type="tns:testServiceResponse"/> <xs:complexType name="testService"> <xs:sequence/> </xs:complexType> <xs:complexType name="testServiceResponse"> <xs:sequence> <xs:element minOccurs="0" name="return" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="getGoods"> <xs:sequence/> </xs:complexType> <xs:complexType name="getGoodsResponse"> <xs:sequence> <xs:element minOccurs="0" name="return" type="tns:goods"/> </xs:sequence> </xs:complexType> <xs:complexType name="goods"> <xs:sequence> <xs:element name="id" type="xs:int"/> <xs:element name="name" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="createGoods"> <xs:sequence> <xs:element minOccurs="0" name="arg0" type="xs:string"/> <xs:element minOccurs="0" name="arg1" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="createGoodsResponse"> <xs:sequence> <xs:element minOccurs="0" name="return" type="tns:goods"/> </xs:sequence> </xs:complexType> <xs:complexType name="exceptionTrace"> <xs:sequence> <xs:element minOccurs="0" name="trace" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="sayHelloTo"> <xs:sequence> <xs:element minOccurs="0" name="text" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="sayHelloToResponse"> <xs:sequence> <xs:element minOccurs="0" name="return" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="exceptionTest"> <xs:sequence> <xs:element minOccurs="0" name="text" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="exceptionTestResponse"> <xs:sequence/> </xs:complexType> <xs:element name="MyWebserviceException" type="tns:MyWebserviceException"/> <xs:complexType name="MyWebserviceException"> <xs:sequence> <xs:element minOccurs="0" name="exceptionTrace" type="tns:exceptionTrace"/> <xs:element minOccurs="0" name="message" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema> </wsdl:types> <wsdl:message name="testService"> <wsdl:part element="tns:testService" name="parameters"></wsdl:part> </wsdl:message> <wsdl:message name="exceptionTestResponse"> <wsdl:part element="tns:exceptionTestResponse" name="parameters"></wsdl:part> </wsdl:message> <wsdl:message name="createGoodsResponse"> <wsdl:part element="tns:createGoodsResponse" name="parameters"></wsdl:part> </wsdl:message> <wsdl:message name="getGoods"> <wsdl:part element="tns:getGoods" name="parameters"></wsdl:part> </wsdl:message> <wsdl:message name="testServiceResponse"> <wsdl:part element="tns:testServiceResponse" name="parameters"></wsdl:part> </wsdl:message> <wsdl:message name="createGoods"> <wsdl:part element="tns:createGoods" name="parameters"></wsdl:part> </wsdl:message> <wsdl:message name="sayHelloTo"> <wsdl:part element="tns:sayHelloTo" name="parameters"></wsdl:part> </wsdl:message> <wsdl:message name="exceptionTest"> <wsdl:part element="tns:exceptionTest" name="parameters"></wsdl:part> </wsdl:message> <wsdl:message name="getGoodsResponse"> <wsdl:part element="tns:getGoodsResponse" name="parameters"></wsdl:part> </wsdl:message> <wsdl:message name="MyWebserviceException"> <wsdl:part element="tns:MyWebserviceException" name="MyWebserviceException"></wsdl:part> </wsdl:message> <wsdl:message name="sayHelloToResponse"> <wsdl:part element="tns:sayHelloToResponse" name="parameters"></wsdl:part> </wsdl:message> <wsdl:portType name="WebserviceSEI"> <wsdl:operation name="testService"> <wsdl:input message="tns:testService" name="testService"></wsdl:input> <wsdl:output message="tns:testServiceResponse" name="testServiceResponse"></wsdl:output> </wsdl:operation> <wsdl:operation name="getGoods"> <wsdl:input message="tns:getGoods" name="getGoods"></wsdl:input> <wsdl:output message="tns:getGoodsResponse" name="getGoodsResponse"></wsdl:output> </wsdl:operation> <wsdl:operation name="createGoods"> <wsdl:input message="tns:createGoods" name="createGoods"></wsdl:input> <wsdl:output message="tns:createGoodsResponse" name="createGoodsResponse"></wsdl:output> <wsdl:fault message="tns:MyWebserviceException" name="MyWebserviceException"></wsdl:fault> </wsdl:operation> <wsdl:operation name="sayHelloTo"> <wsdl:input message="tns:sayHelloTo" name="sayHelloTo"></wsdl:input> <wsdl:output message="tns:sayHelloToResponse" name="sayHelloToResponse"></wsdl:output> </wsdl:operation> <wsdl:operation name="exceptionTest"> <wsdl:input message="tns:exceptionTest" name="exceptionTest"></wsdl:input> <wsdl:output message="tns:exceptionTestResponse" name="exceptionTestResponse"></wsdl:output> <wsdl:fault message="tns:MyWebserviceException" name="MyWebserviceException"></wsdl:fault> </wsdl:operation> </wsdl:portType> <wsdl:binding name="HelloSoapSoapBinding" type="tns:WebserviceSEI"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsaw:UsingAddressing xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" wsdl:required="false"/> <wsp:PolicyReference URI="#HelloSoapSoapBinding_WSAM_Addressing_Policy"/> <wsdl:operation name="testService"> <soap:operation soapAction="" style="document"/> <wsdl:input name="testService"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="testServiceResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="getGoods"> <soap:operation soapAction="" style="document"/> <wsdl:input name="getGoods"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="getGoodsResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="createGoods"> <soap:operation soapAction="" style="document"/> <wsdl:input name="createGoods"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="createGoodsResponse"> <soap:body use="literal"/> </wsdl:output> <wsdl:fault name="MyWebserviceException"> <soap:fault name="MyWebserviceException" use="literal"/> </wsdl:fault> </wsdl:operation> <wsdl:operation name="sayHelloTo"> <soap:operation soapAction="" style="document"/> <wsdl:input name="sayHelloTo"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="sayHelloToResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="exceptionTest"> <soap:operation soapAction="" style="document"/> <wsdl:input name="exceptionTest"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="exceptionTestResponse"> <soap:body use="literal"/> </wsdl:output> <wsdl:fault name="MyWebserviceException"> <soap:fault name="MyWebserviceException" use="literal"/> </wsdl:fault> </wsdl:operation> </wsdl:binding> <wsdl:service name="HelloSoap"> <wsdl:port binding="tns:HelloSoapSoapBinding" name="HelloSoapPort"> <soap:address location="http://localhost:8080/soap/webserviceSEI"/> </wsdl:port> </wsdl:service> <wsp:Policy xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="HelloSoapSoapBinding_WSAM_Addressing_Policy"> <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" wsp:Optional="true"> <wsp:Policy/> </wsam:Addressing> </wsp:Policy> </wsdl:definitions> |
4. Адресация на клиенте
На основании wsdl с использованием адресации были сгенерированы классы на клиенте. Как это делается описано в отдельной статье доступной на сайте.
Для включения адресации на стороне клиента используется метод factoryBean.getFeatures().add(new WSAddressingFeature());
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package ru.javastudy.main; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import org.apache.cxf.ws.addressing.WSAddressingFeature; import ru.javastudy.ws.soap.WebserviceSEI; import javax.xml.soap.*; /** * Created for JavaStudy.ru on 18.06.2016. */ public class ClientMain { public static void main(String[] args) throws SOAPException { String soapURL = "http://localhost:8080/soap/webserviceSEI"; JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean(); factoryBean.setServiceClass(WebserviceSEI.class); factoryBean.setAddress(soapURL); factoryBean.getFeatures().add(new WSAddressingFeature()); WebserviceSEI sei = (WebserviceSEI) factoryBean.create(); String result = sei.sayHelloTo("JavaStudy client!"); System.out.println(result); } } |
Если запустить метод main, то в консоль выведется ответ от сервера: Hello to JavaStudy client!. Простым способом проверки включенной адресации является использование популярной утилиты SoapUI. Как его запустить и настроить описано в SOAP java веб сервис. Пример Hello World example.
В результате запроса к серверу мы увидим в заголовке MessageID. В этом теге описан ID клиента, от которого пришел запрос и следовательно этот ID можно использовать для отправки ответа сервера.