Nimrod Dayan
Nimrod Dayan

Reputation: 3100

No Endpoint mapping found using annotation driven Spring WS with dynamic wsdl and JAXB

I'm using annotation driven Spring WS 2.0.4 to create a simple Webservice, but the enpoint mapping was not found.

Input and Output are JAXB Elements.

The Webservice is running with Java 1.7 on Tomcat 7 which shows a warning in the catalina log:

WARNING: No endpoint mapping found for [SaajSoapMessage {http://mycompany.com/hr/schemas}HolidayRequest]

The code is available for download here

Schema (WEB-INF/hr-data-contract.xsd):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://mycompany.com/hr/schemas" 
        xmlns:hr="http://mycompany.com/hr/schemas" 
        elementFormDefault="qualified">

        <xs:element name="HolidayRequest">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="empId" type="xs:integer" />
                    <xs:element name="days" type="xs:integer" />
                </xs:sequence>
            </xs:complexType>
        </xs:element>
        <xs:element name="HolidayResponse">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="empId" type="xs:integer" />
                    <xs:element name="isApproved" type="xs:boolean" />
                </xs:sequence>
            </xs:complexType>
        </xs:element>
</xs:schema>

Spring config (/WEB-INF/spring-ws-servlet.xml)

<sws:annotation-driven/>

    <context:component-scan base-package="com.mycompany.hr.model" />

    <sws:dynamic-wsdl 
        id="holiday" 
        portTypeName="HumanResource" 
        locationUri="/holidayService/"
        targetNamespace="http://mycompany.com/hr/definitions">
        <sws:xsd location="/WEB-INF/hr-data-contract.xsd" />
    </sws:dynamic-wsdl>

Endpoint (src/main/com/mycompany/hr/service/HolidayEndpoint.java)

@Endpoint
public class HolidayEndpoint {

    private static final String NAMESPACE_URI = "http://mycompany.com/hr/schemas";

    private HolidayService holidaySvc;

    @Autowired
    public HolidayEndpoint(HolidayService holidaySvc) {
        this.holidaySvc = holidaySvc;
    }

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "HolidayRequest")
    @ResponsePayload
    public JAXBElement<HolidayResponse> handleHolidayRequest(@RequestPayload HolidayRequest request) {

        HolidayResponse response = new HolidayResponse();

        response.setIsApproved(holidaySvc.requestHoliday(request.getEmpId(), request.getDays()));
        response.setEmpId(request.getEmpId());

        return new JAXBElement<HolidayResponse>(
                new QName(
                    NAMESPACE_URI,
                "HolidayResponse"),
                HolidayResponse.class,
                response);
    }
}

And this is the auto-generated WSDL:

<wsdl:definitions targetNamespace="http://mycompany.com/hr/definitions" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch="http://mycompany.com/hr/schemas" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://mycompany.com/hr/definitions">
   <wsdl:types>
      <xs:schema elementFormDefault="qualified" targetNamespace="http://mycompany.com/hr/schemas" xmlns:hr="http://mycompany.com/hr/schemas" xmlns:xs="http://www.w3.org/2001/XMLSchema">
         <xs:element name="HolidayRequest">
            <xs:complexType>
               <xs:sequence>
                  <xs:element name="empId" type="xs:integer"/>
                  <xs:element name="days" type="xs:integer"/>
               </xs:sequence>
            </xs:complexType>
         </xs:element>
         <xs:element name="HolidayResponse">
            <xs:complexType>
               <xs:sequence>
                  <xs:element name="empId" type="xs:integer"/>
                  <xs:element name="isApproved" type="xs:boolean"/>
               </xs:sequence>
            </xs:complexType>
         </xs:element>
      </xs:schema>
   </wsdl:types>
   <wsdl:message name="HolidayResponse">
      <wsdl:part element="sch:HolidayResponse" name="HolidayResponse"/>
   </wsdl:message>
   <wsdl:message name="HolidayRequest">
      <wsdl:part element="sch:HolidayRequest" name="HolidayRequest"/>
   </wsdl:message>
   <wsdl:portType name="HumanResource">
      <wsdl:operation name="Holiday">
         <wsdl:input message="tns:HolidayRequest" name="HolidayRequest"/>
         <wsdl:output message="tns:HolidayResponse" name="HolidayResponse"/>
      </wsdl:operation>
   </wsdl:portType>
   <wsdl:binding name="HumanResourceSoap11" type="tns:HumanResource">
      <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="Holiday">
         <soap:operation soapAction=""/>
         <wsdl:input name="HolidayRequest">
            <soap:body use="literal"/>
         </wsdl:input>
         <wsdl:output name="HolidayResponse">
            <soap:body use="literal"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:service name="HumanResourceService">
      <wsdl:port binding="tns:HumanResourceSoap11" name="HumanResourceSoap11">
         <soap:address location="http://localhost:8080/holidayService/holidayService/"/>
      </wsdl:port>
   </wsdl:service>
</wsdl:definitions>

Here is a sample request I'm sending to http://localhost:8080/holidayService/holidayService/ using SoapUI

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://mycompany.com/hr/schemas">
   <soapenv:Header/>
   <soapenv:Body>
      <sch:HolidayRequest>
         <sch:empId>1</sch:empId>
         <sch:days>3</sch:days>
      </sch:HolidayRequest>
   </soapenv:Body>
</soapenv:Envelope>

Upvotes: 1

Views: 8551

Answers (2)

李英权
李英权

Reputation: 31

An endpoint should not be enhanced by aop; otherwise, springws can not map soaps to it!

Upvotes: 1

jddsantaella
jddsantaella

Reputation: 3687

Localpart should be "HolidayRequest"

Edit: try this:

@PayloadRoot(namespace = NAMESPACE_URI, localPart = "HolidayRequest")
public HolidayResponse handleHolidayRequest(HolidayRequest request) {

    HolidayResponse response = new HolidayResponse();  // JAXB object

    response.setIsApproved(holidaySvc.requestHoliday(request.getEmpId(), request.getDays()));
    response.setEmpId(request.getEmpId());

    return response;
}

Edit 2 (your base package should include the endpoint class!!):

your configuration should look like:

<sws:annotation-driven/>

<context:component-scan base-package="com.mycompany" />

<!-- enable autowire -->
<context:annotation-config />   

<sws:dynamic-wsdl 
    id="holiday" 
    portTypeName="HumanResource" 
    locationUri="/holidayService/"
    targetNamespace="http://mycompany.com/hr/definitions">
    <sws:xsd location="/WEB-INF/hr-data-contract.xsd" />
</sws:dynamic-wsdl>

Upvotes: 4

Related Questions