I've made a WS server from a WSDL definition (Contract first approach). I've generated the Java artifacts with wsimport and tested the service. Now I've got a problem. Some (not all) arguments of an operation requests are unmarshalled as null! The web service is SOAP based. The wsdl follow the document-literal convention. So, this is the schema imported by AbstractFDSInfo.wsdl:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.example.com/FDSControl"
xmlns:com="http://www.example.com/FDSCommon"
targetNamespace="http://www.example.com/FDSControl"
elementFormDefault="qualified">
<import namespace="http://www.example.com/FDSCommon" schemaLocation="FDSCommon.xsd"/>
<complexType name="PassengerList">
<sequence>
<element ref="com:Passenger" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="FlightInstanceStatusList">
<sequence>
<element type="com:flightInstanceStatus" name="Status" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
<!-- other operation types here -->
<element name="setPassengerBoarded">
<complexType>
<sequence>
<element ref="com:FlightInstanceId"/>
<element type="string" name="Passenger"/>
</sequence>
</complexType>
</element>
<element name="setPassengerBoardedResponse">
<complexType/>
</element>
<element name="passengerBoardingException">
<complexType>
<sequence>
<element type="token" name="Reason"/>
<element type="string" name="Detail"/>
</sequence>
</complexType>
</element>
<!-- Other operation types here --->
And here is the FDSControlAbstract.wsdl:
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="FDSControlAbstract"
xmlns:tns="http://www.example.com/FDSControl.wsdl"
xmlns:con="http://www.example.com/FDSControl"
xmlns:com="http://www.example.com/FDSCommon"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://www.example.com/FDSControl.wsdl">
<types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://www.example.com/FDSCommon" schemaLocation="FDSCommon.xsd"/>
<xsd:import namespace="http://www.example.com/FDSControl" schemaLocation="FDSControl.xsd"/>
</xsd:schema>
</types>
<message name="setPassengerBoardedRequest">
<part element="con:setPassengerBoarded" name="Params"/>
</message>
<message name="setPassengerBoardedResponse">
<part element="con:setPassengerBoardedResponse" name="Params"/>
</message>
<message name="passengerBoardingException">
<part element="con:passengerBoardingException" name="Params"/>
</message>
<!-- other messages here -->
<portType name="FDSBoardingPortType">
<!-- other operations here -->
<operation name="setPassengerBoarded">
<documentation>
Sets a passenger as boarded. If the passenger is already boarded,
or the flight instance is not in the boarding status, an exception
is returned.
</documentation>
<input message="tns:setPassengerBoardedRequest"/>
<output message="tns:setPassengerBoardedResponse"/>
<fault message="tns:flightInstanceNotFoundException"
name="flightInstanceNotFoundException"/>
<fault message="tns:passengerBoardingException"
name="passengerBoardingException"/>
<fault message="tns:flightStatusException"
name="flightStatusException"/>
</operation>
</portType>
<!-- other port types here -->
</definitions>
Here is the FDSControl.wsdl:
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="FDSControl"
xmlns:tns="http://www.example.com/FDSControl.wsdl"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://www.example.com/FDSControl.wsdl"
elementFormDefault="qualified">
<import namespace="http://www.example.com/FDSControl.wsdl" location="FDSControlAbstract.wsdl"/>
<!-- other bindings here-->
<binding name="FDSBoardingSOAP" type="tns:FDSBoardingPortType">
<!-- other operations here -->
<operation name="setPassengerBoarded">
<soap:operation soapAction="http://www.example.com/FDSControl/setPassengerBoarded"/>
<input> <soap:body use="literal"/> </input>
<output> <soap:body use="literal"/> </output>
<fault name="flightInstanceNotFoundException">
<soap:fault name="flightInstanceNotFoundException" use="literal"/>
</fault>
<fault name="passengerBoardingException">
<soap:fault name="passengerBoardingException" use="literal"/>
</fault>
<fault name="flightStatusException">
<soap:fault name="flightStatusException" use="literal"/>
</fault>
</operation>
</binding>
<service name="FDSBoardingSOAPService">
<port name="FDSBoardingPortType" binding="tns:FDSBoardingSOAP">
<soap:address location="http://localhost:7070/fdscontrol"/>
</port>
</service>
</definitions>
Now here is the definition of the java class implementing the web service:
@WebService(name="FDSBoarding",
endpointInterface="it.polito.dp2.FDS.lab4.server.gen.FDSBoardingPortType",
wsdlLocation="META-INF/FDSControl.wsdl",
portName="FDSBoardingPortType",
serviceName="FDSBoardingSOAPService",
targetNamespace="http://www.example.com/FDSControl.wsdl")
})
public class FDSControlImpl implements FDSBoardingPortType {
private FlightManager manager;
public FDSControlImpl(FlightManager manager) {
this.manager = manager;
}
//other methods here
@Override
public SetPassengerBoardedResponse setPassengerBoarded(SetPassengerBoarded params)
throws FlightInstanceNotFoundException_Exception, FlightStatusException_Exception, PassengerBoardingException_Exception {
return manager.setPassengerBoarded(params);
}
}
You can see I kept the parameters wrapped in a single class. Now the problem is that, whenever I send a request for setPassengerBoarded(), the server returns null as params.getPassenger() Is there something wrong with my structure/definitions?
I was compiling two different WSDLs to the same package. I split the generated code in two packages and the problem disappeared, even though now I have duplicate classes and thus I need to convert back and forth between the these...