Борьба за создание SOAP-сервиса на основе файла wsdl с помощью cxf - PullRequest
0 голосов
/ 17 января 2019

Я пытаюсь создать работающий SOAP-сервис с Apache cxf из wsdl-файла. Я обращаюсь к службе, но уже получаю то же сообщение об исключении, которое вы видели в последнем фрагменте кода. Я покажу вам еще несколько фрагментов кода, потому что я новичок в создании веб-сервисов такого рода и не знаю, где моя ошибка. Спасибо за вашу помощь!

Начиная с моего wsdl-файла:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="DataService" targetNamespace="http://service.data.com"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema"
              xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
              xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
              xmlns:test="http://service.data.com">

<wsdl:types>
    <xsd:schema targetNamespace="http://service.data.com"
                xmlns="http://www.w3.org/2001/XMLSchema"
                elementFormDefault="qualified">
        <element name="DataReq" type="test:DataReqType"/>
        <element name="DataRsp" type="test:DataRspType"/>

        <complexType name="DataReqType">
            <sequence>
                <element minOccurs="0" name="DataXML" nillable="true" type="test:DataXML"/>
            </sequence>
        </complexType>
        <complexType name="DataRspType">
            <sequence>
                <element name="DataError" type="test:DataError"/>
                <element name="success" nillable="true" type="int"/>
            </sequence>
        </complexType>

        <complexType name="DataXML">
            <sequence>
                <element name="xmlString" type="test:String200"/>
            </sequence>
        </complexType>
        <complexType name="DataError">
            <sequence>
                <element name="errorCode" nillable="false" type="int"/>
                <element name="errorMessage" nillable="true" type="test:String40"/>
            </sequence>
        </complexType>

        <simpleType name="String40">
            <restriction base="string">
                <maxLength value="40"/>
            </restriction>
        </simpleType>
        <simpleType name="String200">
            <restriction base="string">
                <maxLength value="200"/>
            </restriction>
        </simpleType>

    </xsd:schema>
</wsdl:types>

<wsdl:message name="PostDataReq">
    <wsdl:part name="body" element="test:DataReq"/>
</wsdl:message>
<wsdl:message name="PostDataRsp">
    <wsdl:part name="body" element="test:DataRsp"/>
</wsdl:message>

<wsdl:portType name="DataPortType">
    <wsdl:operation name="dataImport">
        <wsdl:input message="test:PostDataReq"/>
        <wsdl:output message="test:PostDataRsp"/>
    </wsdl:operation>
</wsdl:portType>

<wsdl:binding name="DataSOAPBinding" type="test:DataPortType">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="dataImport">
        <soap:operation soapAction="http://service.data.com/dataImport"/>
        <wsdl:input>
            <soap:body use="literal"/>
        </wsdl:input>
        <wsdl:output>
            <soap:body use="literal"/>
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>

<wsdl:service name="DataService">
    <wsdl:port binding="test:DataSOAPBinding" name="DataServicePort">
        <soap:address location="http://localhost:32080/test/services/dataImport"/>
    </wsdl:port>
</wsdl:service>

Мой cxf-servlet.xml с бином для размещения сервиса:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jaxws="http://cxf.apache.org/jaxws"
   xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://cxf.apache.org/jaxws
         http://cxf.apache.org/schemas/jaxws.xsd">

<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

<jaxws:endpoint id="DataService"
                implementor="com.test.DataService"
                address="/dataImport">
</jaxws:endpoint>

Результат, полученный при запросе сервиса в браузере, добавил "? Wsdl":

<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://service.data.com"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:ns2="http://schemas.xmlsoap.org/soap/http"
xmlns:ns1="http://data.server.test.com/" name="DataService"
targetNamespace="http://service.data.com">
<wsdl:import location="http://localhost:32080/dataImport?wsdl=DataService.wsdl"
 namespace="http://data.server.test.com/"> </wsdl:import>
 <wsdl:binding name="DataServiceSoapBinding" type="ns1:DataService">
 <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
</wsdl:binding>
<wsdl:service name="DataService">
    <wsdl:port binding="tns:DataServiceSoapBinding" name="DataServicePort">
        <soap:address location="http://localhost:32080/dataImport"/>
    </wsdl:port>
 </wsdl:service>
</wsdl:definitions>

Пост-запрос, который я делаю с SOAP-UI:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ser="http://service.data.com">
<soapenv:Header/>
<soapenv:Body>
    <ser:DataReq>
        <ser:DataXML>
            <ser:xmlString>Test</ser:xmlString>
        </ser:DataXML>
    </ser:DataReq>
</soapenv:Body>
</soapenv:Envelope>

И он отвечает следующим исключением:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
    <soap:Fault>
        <faultcode>soap:Client</faultcode>
        <faultstring>Message part {http://service.data.com}DataReq was not recognized.
            (Does it exist in service WSDL?)</faultstring>
        </soap:Fault>
    </soap:Body>
</soap:Envelope>

1 Ответ

0 голосов
/ 23 января 2019

Я нашел решение, начав новый отдельный проект с нуля. Я сделал несколько ошибок в своем коде.

1) В cxf-servlet.xml мне нужно вызвать сгенерированный DataPortImpl вместо DataService :

<jaxws:endpoint id="DataService"
                implementor="com.test.DataPortImpl"
                address="/dataImport">
</jaxws:endpoint>

2) Нарушение некоторых конвенций в моем wsdl-файле, которые требуются для использования cxf:

Необходимо заменить элементы-части сообщения DataReq и DataRsp на Данные для запроса и DataResponse для ответа.

3) Выполнение команды cxf прошло нормально:

wsdl2java -server -impl  -d %pathToDirectory% -p %pathToPackage%
-wsdlLocation classpath:%relativePathToWSDL% %pathToWSDL%
...