I'm trying to work with the Microsoft Exchange EWS protocol, for which Microsoft provide a WSDL file. I'm generate a JAX-WS client library from this using wsimport.
Unfortunately, Microsoft's WSDL file is faulty. One of the things it is getting wrong (apparently) is that all SOAP request parameters are defined as mandatory --- except they're not, they're optional, and in some situations I have to be able to not supply them.
Excerpt from the WSDL file:
<wsdl:operation name="GetUserAvailability">
<soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetUserAvailability" />
<wsdl:input>
<soap:header message="tns:GetUserAvailabilitySoapIn" part="Impersonation" use="literal"/>
<soap:header message="tns:GetUserAvailabilitySoapIn" part="TimeZoneContext" use="literal"/>
<soap:header message="tns:GetUserAvailabilitySoapIn" part="RequestVersion" use="literal"/>
<soap:body parts="GetUserAvailabilityRequest" use="literal" />
<soap:header message="tns:GetUserAvailabilitySoapIn" part="RequestVersion" use="literal"/>
</wsdl:input>
<wsdl:output>
...skipped...
</wsdl:output>
</wsdl:operation>
<wsdl:message name="GetUserAvailabilitySoapIn">
<wsdl:part name="GetUserAvailabilityRequest" element="tns:GetUserAvailabilityRequest" />
<wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
<wsdl:part name="TimeZoneContext" element="t:TimeZoneContext" />
<wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
</wsdl:message>
<xs:element name="ExchangeImpersonation" type="t:ExchangeImpersonationType"/>
If I call this with, say, service.getUserAvailability(request, null, null, version), then I get an <ExchangeImpersonation xsl:nil="true"/> element in the header, and the Exchange server complains about having an extraneous element.
So, I want to edit the WSDL file to make these parameters properly optional. I've tried adding various combinations of wsdl:required=false and minOccurs=0 to various places according to the docs, but wsimport appears to be ignoring them completely --- the resulting code is unchanged.
How do I do this?
Related
I'm trying to use wsimport (or more accurately I'm using the eclipse wizard that uses wsimport) to generate new server side classes for a webservice. The source WSDL comes from the current implementation via the ../ServiceName?wsdl URL.
My problem is that when I publish the new classes and navigate to the new ?wsdl URL the results WSDL is different than the original. This seems to be a cause of errors when the existing clients try to use the new version of the service. Here is a subsection of the WSDL with an example of a difference that seems to cause a problem with the clients:
Original:
<wsdl:message name="executeResponse">
<wsdl:part element="impl:ServiceNameResult" name="ServiceNameResult"/>
</wsdl:message>
<wsdl:message name="executeRequest">
<wsdl:part element="impl:executeRequest" name="executeRequest"/>
</wsdl:message>
<wsdl:portType name="ServiceName">
<wsdl:operation name="execute" parameterOrder="executeRequest">
<wsdl:input message="impl:executeRequest" name="executeRequest"/>
<wsdl:output message="impl:executeResponse" name="executeResponse"/>
</wsdl:operation>
</wsdl:portType>
New:
<wsdl:message name="executeResponse">
<wsdl:part element="tns:ServiceNameResult" name="ServiceNameResult">
</wsdl:part>
</wsdl:message>
<wsdl:message name="execute">
<wsdl:part element="tns:executeRequest" name="executeRequest">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="ServiceName">
<wsdl:operation name="execute">
<wsdl:input message="tns:execute" name="execute">
</wsdl:input>
<wsdl:output message="tns:executeResponse" name="executeResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
The change is in the portType input message. It gets renamed from "executeRequest" to simply "execute".
I can't figure out why this would change or how to correct it in the java classes. All the annotations seem correct.
It seems like the missing "Request" suffix is a feature and not a bug of CXF. What I need to do is either update my clients or implement serverside interceptors:
http://cxf.apache.org/docs/interceptors.html
This:
You will need to subclass org.apache.cxf.service.factory.DefaultServiceConfiguration and override getInputMessageName method to append the QName with "Request". Then, you will have to configure CXF to point the service configuration to your subclass
Also seems like a good solution if I can figure out how to do it. https://stackoverflow.com/questions/27818072/subclassing-defaultserviceconfiguration
I'm trying to create a webservice using the New -> Web Service from WSDL in Netbeans 7.1.2.
I went ahead and created a WSDL using XML spy. Here is the basic WSDL that I've created:
<wsdl:definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://www.w3.org/ns/ws-policy"
xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://planningservice.ohs.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns="http://docs.oasis-open.org/wsn/t-1" xmlns:ns1="http://www.isotc211.org/2005/gco" xmlns:ns2="http://www.isotc211.org/2005/gmd" xmlns:ns3="http://www.isotc211.org/2005/gsr" xmlns:ns4="http://www.isotc211.org/2005/gss" xmlns:ns5="http://www.isotc211.org/2005/gts" xmlns:ns6="http://www.opengis.net/gml/3.2" xmlns:ns7="http://www.opengis.net/ows/1.1" xmlns:ns8="http://www.opengis.net/sps/2.0" xmlns:ns9="http://www.opengis.net/swe/2.0" xmlns:ns10="http://www.opengis.net/swes/2.0" xmlns:ns11="http://www.w3.org/2005/08/addressing" name="PlanningService" targetNamespace="http://planningservice.ohs.com/">
<wsdl:import namespace="http://www.opengis.net/sps/2.0" location="http://schemas.opengis.net/sps/2.0/spsGetFeasibility.xsd"/>
<wsdl:types>
<xsd:schema>
<xsd:import namespace="http://ps.ca"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="GetFeasibility">
<wsdl:part name="parameters" type="ns8:GetFeasibilityType"/>
</wsdl:message>
<wsdl:message name="GetFeasibilityResponse">
<wsdl:part name="parameters" type="ns8:GetFeasibilityResponseType"/>
</wsdl:message>
<wsdl:portType name="PlanningService">
<wsdl:operation name="GetFeasibility">
<wsdl:input message="tns:GetFeasibility" wsam:Action="http://planningservice.ohs.com/PlanningService/getFeasibility"/>
<wsdl:output message="tns:GetFeasibilityResponse" wsam:Action="http://planningservice.ohs.com/PlanningService/getFeasibilityResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="PlanningSerivcePortBinding" type="tns:PlanningService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetFeasibility">
<soap:operation soapAction="' '"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="PlanningSerivce">
<wsdl:port name="PlanningService" binding="tns:PlanningSerivcePortBinding">
<soap:address location="http://localhost:8080/PlanningService/"/>
</wsdl:port>
</wsdl:service>
When I try using the above I the 'New Web Service From WSDL' wizard says "There is no service in specified WSDL file."
If I don't specify the location attribute, like so:
<wsdl:service name="PlanningSerivce">
<wsdl:port name="PlanningService" binding="tns:PlanningSerivcePortBinding">
<soap:address/>
</wsdl:port>
</wsdl:service>
I don't have that notification but during the creation of the Web Service I get an error that says the attribute is missing.
So my question is what do I put in the location attribute to get Netbeans to recognize that there is a service defined, given that it isn't deployed anywhere!
Thanks all!
~D
The WSDL document as provided is not entirely valid.
The first issue is the declaration of the document style but the message declaration in the rpc style. Rpc uses message parts defined in terms of 'type's. Document uses message parts defined in terms of 'element's. I looked over the XSD imported into the WSDL and found the 'GetFeasibility' and 'GetFeasibilityResponse' elements defined there. So, changing the wsdl:message nodes to
<wsdl:message name="GetFeasibility">
<wsdl:part name="parameters" element="ns8:GetFeasibility"/>
</wsdl:message>
<wsdl:message name="GetFeasibilityResponse">
<wsdl:part name="parameters" element="ns8:GetFeasibilityResponse"/>
</wsdl:message>
helps by making the message definitions consistent with the document style service.
There is a nice writeup at http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/ about wsdl construction w.r.t. declared styles.
The next issue is the schema import. There are special restrictions around the wsdl:import statement. In general, the proper place to pull in schemas is the wsdl:types section. If you use something like
<wsdl:types>
<xsd:schema>
<xsd:import namespace="http://www.opengis.net/sps/2.0"
schemaLocation="http://schemas.opengis.net/sps/2.0/spsGetFeasibility.xsd"/>
<xsd:import namespace="http://ps.ca"/>
</xsd:schema>
</wsdl:types>
(not sure of the value of the ps.ca import), the relevant types are available for the wsdl import machinery. A writeup of wsdl importing is at http://scn.sap.com/people/kevin.liu/blog/2004/06/28/a-note-on-wsdl-and-xsd-imports
Once these modifications were made, wsimport still saw an error in the form of a name collision in the supporting schemas at opengis.net, but hopefully this gives you enough to move our project along a bit and you can focus on the name collision rather than fighting the wsdl construction.
I generate my web service from WSDL file. But I need t o define in this file that my methods in SkeletonInterface thow Axis Fault Exception.
Smth like:
void method() throws AxisFault{....}
In which way I can do this (in WSDL).
Thanks.
In short, it's bad practice to reuse AxisFault for your own application faults. When I see AxisFault, it signals that something internal to the Axis autogen code failed. This could include your exception wrapped inside of it.
First, I want to address your pseudcode.
void method() throws AxisFault{....}
This pseudocode indicates that you want a method with no input, no output, but still have an exception. If I assume this, then that design is not recommended (I'm not even sure if it is possible). If you want something to trigger something to happen with no output, an empty output message is preferable to an exception. Exceptions should only be used when something uncommon happens.
If you meant the above code as an abstract example and you do have input/output, then the correct approach would be to make up your own fault. Using your own fault allows you to control behavior and more accurately describe what is failing. You may also need several faults in the future so using AxisFault is not beneficial in that case.
<wsdl:definitions ...>
...
<wsdl:message name="MyFault">
<wsdl:part name="parameters" element="def:MyFault">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="MyPortType">
<wsdl:operation name="doStuff">
<wsdl:input message="tns:MyRequest">
</wsdl:input>
<wsdl:output message="tns:MyResponse">
</wsdl:output>
<wsdl:fault name="MyFault" message="tns:MyFault">
</wsdl:fault>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="MyBinding" type="tns:MyPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="doStuff">
<soap:operation soapAction="namespace/operationName"/>
<wsdl:input name="MyRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="MyResponse">
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="MyFault">
<soap:body use="literal"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
...
</wsdl:definitions>
That said, AxisFault does happen for web service operation calls. For your client stub code, it should throw a RemoteException. If you take a look at your autogen Stub code, you should see that does in fact throw an AxisFault which extends RemoteException.
using the faults
<definitions ...>
<message name="empty"/>
<message name="InsufficientFundsFault">
<part name="balance" type="xsd:int"/>
</message>
<portType name="Bank">
<operation name="throwException">
<input message="tns:empty"/>
<output message="tns:empty"/>
<fault name="fault" message="tns:InsufficientFundFault"/>
</operation>
</portType>
...
</definitions>
Im trying to call a Java web service created using Axis from PHP code.The webservice is hosted on my LAN. I am able to call the web service successfully using SoapUI. I have the PHP Soap Extension installed.
However,im not sure whether my PHP code is correct. Below is my PHP code.
<?php
$client = new SoapClient('http://machinename/axis/services/Compiere?wsdl');
$params = array('in0'=> '124','in1'=>'1');
$result = $client->__SoapCall('createOrder',array($params));
print $result->createOrderReturn;
?>
The WSDL is as follows :
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://compservice.com" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://compservice.com" xmlns:intf="http://compservice.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)-->
<wsdl:message name="createOrderRequest">
<wsdl:part name="in0" type="xsd:int"/>
<wsdl:part name="in1" type="xsd:int"/>
</wsdl:message>
<wsdl:message name="createOrderResponse">
<wsdl:part name="createOrderReturn" type="xsd:string"/>
</wsdl:message>
<wsdl:portType name="OrderServiceInt">
<wsdl:operation name="createOrder" parameterOrder="in0 in1">
<wsdl:input message="impl:createOrderRequest" name="createOrderRequest"/>
<wsdl:output message="impl:createOrderResponse" name="createOrderResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CompiereSoapBinding" type="impl:OrderServiceInt">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="createOrder">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="createOrderRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://compservice.com" use="encoded"/>
</wsdl:input>
<wsdl:output name="createOrderResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://compservice.com" use="encoded"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="OrderServiceIntService">
<wsdl:port binding="impl:CompiereSoapBinding" name="Compiere">
<wsdlsoap:address location="http://nuca232/axis/services/Compiere"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Is my PHP code correct ?
Please help.
Thank You.
Why don't you try the direct mode?
<?php
$client = new SoapClient('http://machinename/axis/services/Compiere?wsdl');
$params = array('in0'=> '124','in1'=>'1');
$result = $client->createOrder( $parms );
print_r($result);
Instead of using $client->__SoapCall('createOrder',array($params));
As the manual says: "Usually, in WSDL mode, SOAP functions can be called as methods of the SoapClient object"
we are migrating from WebLogic web-services to Spring-WS (1.5.X).
There is currently one issue we are facing:
We need to pass a context object (on WLS it is passed as SOAP-Header element) to other services that are still running on WLS from the Spring-WS powered service. The header element is still formulated on client side and the newly created WS (Spring-WS) should just pass it to other services.
I can imagine how the custom element would be passed: override the doWithMessage(WebServiceMessage message) method...
Is there a way to generate the wsdl with the help of DefaultWsdl11Definition to contain that custom header element?
See the example:
<wsdl:operation name="GetSomeInformation">
<soap:operation
soapAction="http://www.dummyservice.com/InformationService/GetSomeInformation" />
<wsdl:input>
<soap:body use="literal" />
<soap:header message="ctx:ServiceContextMessage" part="serviceContext" use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
<wsdl:fault name="Error">
<soap:fault name="Error" use="literal" />
</wsdl:fault>
</wsdl:operation>
Thanks for help
We ran into a similar issue on my project. Check into extending SuffixBasedPortTypesProvider, SuffixBasedMessagesProvider, and Soap11Provider. We use the InliningXsdSchemaTypesProvider to import the schema we use to build the WSDL. If you run the WSDL generation through the debugger you'll get the hang of how it works. The Spring code is easy to follow and extend.