I am learning WSDL using online documentation, for WSDL Ports it is mentioned that:
A port MUST NOT specify more than one address.
A port MUST NOT specify any binding information other than address
information.
and the example given is:
<portType name="StockQuotePortType">
<operation name="GetLastTradePrice">
<input message="tns:GetLastTradePriceInput"/>
<output message="tns:GetLastTradePriceOutput"/>
</operation>
</portType>
What is address in this example? also what it means that A port MUST NOT specify any binding information other than address information.? Please help me in understanding the concepts.
I think you have referred wrong example, It was talking about port under service tag. Something like this,
<wsdl:service name="StockQuote">
<wsdl:port name="StockQuoteSoap" binding="tns:StockQuoteSoap">
<soap:address location="http://www.webservicex.net/stockquote.asmx" />
</wsdl:port>
<wsdl:port name="StockQuoteSoap12" binding="tns:StockQuoteSoap12">
<soap12:address location="http://www.webservicex.net/stockquote.asmx" />
</wsdl:port>
<wsdl:port name="StockQuoteHttpGet" binding="tns:StockQuoteHttpGet">
<http:address location="http://www.webservicex.net/stockquote.asmx" />
</wsdl:port>
<wsdl:port name="StockQuoteHttpPost" binding="tns:StockQuoteHttpPost">
<http:address location="http://www.webservicex.net/stockquote.asmx" />
</wsdl:port>
Here you can see address location of this particular webservice i.e.
http://www.webservicex.net/stockquote.asmx
That means each time, you will send your request message on this address location under a specific binding.
There are 4 ports or you can say 1 webservices i.e. StockQuote but you can call it in 4 different ways as per bindings.
Bindings defines message format and protocol details for each port. For example.
<wsdl:binding name="StockQuoteSoap" type="tns:StockQuoteSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="GetQuote">
<soap:operation soapAction="http://www.webserviceX.NET/GetQuote" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
Lets say you are calling StockQuote webservice using "StockQuoteSoap" port. So while sending your request you will use above binding as referred in port tag.
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
http transport protocol and soap messaging protocol.
<wsdl:binding name="StockQuoteSoap" type="tns:StockQuoteSoap">
tns:StockQuoteSoap is referring at your port type
<wsdl:operation name="GetQuote">
GetQuote is your operation name.
This is more concerned, how your webservice is implemented on server side for this binding.
You can consider operation name as method name and port type as class name in traditional programming language.
Full port type difinition can be seen in wsdl as
<wsdl:portType name="StockQuoteSoap">
<wsdl:operation name="GetQuote">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Get Stock quote for a company Symbol</wsdl:documentation>
<wsdl:input message="tns:GetQuoteSoapIn" />
<wsdl:output message="tns:GetQuoteSoapOut" />
</wsdl:operation>
That means GetQuote method of StockQuoteSoap class will be executed at server for given input and output message in definition.
soap:operation soapAction="http://www.webserviceX.NET/GetQuote" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output
your binding also specifies input and output message format and style
SOAP Action is optional feature which is used by server to filter out incoming request.
(3) If I am developing a service in Java programming then we have classes defined in Java package, so where the package structure go in this WSDL?
Lets take an example where, you want to publish a webservice at
url "http://testhost:9999/ws/helloexample" in java in package examplePackage.
You have a class or interface named sayHello in which you have defined a method public String helloWorld (String Name).
You are publishing this class using
Endpoint.publish("http://testhost:9899/ws/helloexample", new sayHello());
So your generated wsdl will be mapped like below.
Interface or class name: PortType
Method name: Operation
Method name: input message (request)
Method name+Response: output message (response)
<portType name="sayHello">
<operation name="helloWorld">
<input message="tns:helloWorld"/>
<output message="tns:helloWorldResponse"/>
</operation>
</portType>
Endpoint.publish("http://testhost:9899/ws/helloexample",new sayHello())
: address location
<wsdl:service name="sayHelloService">
<wsdl:port name="sayHelloPort" binding="tns:sayHelloPortBinding">
<soap:address location="http://testhost:9899/ws/helloexample" />
</wsdl:port>
You can use various webservice annotations available like #WebParam, #WebMethod, #WebResult etc to change operation name, message part name, namespace etc in wsdl.
Further addidng binding in generated wsdl,
<wsdl:binding name="sayHelloPortBinding" type="tns:sayHello">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="helloWorld">
<soap:operation soapAction="" style="rpc"/>
<wsdl:input>
<soap:body use="literal" namespace="http://examplePackage" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" namespace="http://examplePackage" />
</wsdl:output>
</wsdl:operation>
SOAPAction can be set in #WebMethod annotation. style can be set in #SOAPBinding anootation.
Related
For production used web service-client mechanism we are implementing new feature pretty much similar to already used.
New method is using the same description like the previous features inside wsdl.
The client side is generated inside Eclipse using Apache Axis (1.).
wsdl
<wsdl:operation name="Work">
<soap:operation soapAction="WORK" style="document"/>
<wsdl:input>
<soap:header message="llws:Header2" part="Header" use="literal"/>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Work">
<wsdl:input message="test:WorkRequestObject"/>
<wsdl:output message="test:WorkResponseObject"/>
</wsdl:operation>
What is confusing me is different syntax of generated method. First method is generated with signature:
public ResponseObject doSomething(RequestObject)
while second method is generated with signature like
public void doSomeOtheWork (RequestObject, javax.xml.rpc.holders.BigIntegerHolder, javax.xml.rpc.holders.StringHolder)
Why is this done this way? Why both methods aren't generated using the same syntax? Could it be that first method is already present and generator is leaving it unchanged whilst second one is generated with the another version/lib are therefor I get another signature?
I have a WSDL like that :
...
<wsdl:message name="myHeader">
<wsdl:part name="parameter" element="header:myHeader"/>
</wsdl:message>
...
<wsdl:operation name="myOperation">
<soap:operation soapAction="myOperation" style="document" />
<wsdl:input name="myOperationRequest">
<soap:header message="mySession:myHeader" part="header" use="literal"/>
<soap:body parts="parameters" use="literal" />
</wsdl:input>
<wsdl:output name="myOperationResponse">
<soap:body parts="parameters" use="literal" />
</wsdl:output>
<wsdl:fault name="myOperationException">
<soap:fault name="createTroubleTicketByValueException" use="literal" />
</wsdl:fault>
</wsdl:operation>
....
I convert my WSDL into Java with wsdl2java, not problem during the conversion with the exsh set to true.
But when I start my application (Spring 4, CXF 2.7), I'm getting the following warning :
2015-09-28 14:19:04,640 WARN [main] o.a.c.s.f.ReflectionServiceFactoryBean(1525) - Method interface ....XXXSessionWSPort.myOperation is configured as BARE but there are more than one parameters with wrong #Webparam annotated or without #WebParam annotated.
If I look closer to the WsPort generated :
#WebResult(name = "myOperationResponse", targetNamespace = "http://myNamespace", partName = "parameters")
#WebMethod(action = "myOperation")
public myOperationResponse myOperation(
#WebParam(partName = "parameters", name = "myOperationRequest", targetNamespace = "http://myNameSpace")
myOperationRequest parameters,
#WebParam(partName = "parameters", name = "myheader", targetNamespace = "http://headerNameSpace", header = true)
myHeader parameters1) throws myOperationException;
Moreover, as a client when I make a call to myOperation CXF/JAXB/Jax-ws/...(?) add a "1" at the end of the myHeader tag, consequently the server cannot handle the header...
After debugging in the class ReflectionServiceFactoryBean, I see the problem coming from the same partName in the two #WebParam.
To correct this, I have to change the header's part name into the WSDL, but I can't : it's not mine.
So I would made this change in the jaxb binding xml file, if possible, how can I do that?
If you have a better solution don't hesitate!
A bit late, but maybe this can help you: "A customization file"
http://java-soa.blogspot.pe/2008/07/parameter-customization-in-jax-ws.html
I'm a bit stuck here. We're trying to write WS Client using Spring WS. The challenge is to handle web services like getVersion() that do not need to pass any values to the server.
Here's a typical Client implementation you'd normally use:
public class MyServiceClient extends WebServiceGatewaySupport {
public String getVersion() {
SomeJaxbGeneratedClass request = new SomeJaxbGeneratedClass();
String response = (String) getWebServiceTemplate().marshalSendAndReceive(request,
new SoapActionCallback("someNameSpace/getVersion"));
return response;
}
}
The issue is when calling getVersion there's no SomeJaxbGeneratedClass to be passed as a request since it's only requesting to get the version number. So my question is what should be passed in as a request (RequestPayload) in this case? Does WebServiceTemplate have another method that would work better?
Here's how getVersion is defined in WSDL:
<WSDL:message name="getVersionRequest"/>
<WSDL:message name="getVersionResponse">
<WSDL:part name="version" type="xsd:string"/>
</WSDL:message>
<portType>
<WSDL:operation name="getVersion">
<WSDL:input message="tns:getVersionRequest"/>
<WSDL:output message="tns:getVersionResponse"/>
</WSDL:operation>
</portType>
<binding>
<WSDL:operation name="getVersion">
<SOAP:operation soapAction="someNameSpace/getVersion"/>
<WSDL:input>
<SOAP:body namespace="someNameSpace" use="literal"/>
</WSDL:input>
<WSDL:output>
<SOAP:body namespace="someNameSpace" use="literal"/>
</WSDL:output>
</WSDL:operation>
</binding>
Any help will be greatly appreciated.
Just want to give everyone an update in case you run into a similar issue. I got this resolved by switching from Spring WS to Spring JAX-WS solution using JaxWsPortProxyFactoryBean.
I have written a web service in a top down way : I wrote de WSDL first, then I used the wsimport tool to produce the WS interface and the proxies, and finally I wrote the WS implementation.
Now, my WS is deployed on a Tomee 1.6 server, and when I invoke it with a ?wsdl parameter, I get a WSDL wich is different from the one I wrote first. In my first WSDL the service name was "ImmoService", whereas in the WSDL I get when invoking the deployed web service, it is "ImmoServiceService".
I first thought it was a bug in Tomee, so I deployed the WS on Glassfish. But I got the same result. It seems that I have missed something. The name of the service in the WSDL produced by the WS should not be the same as the name of the service in the WSDL from which the WS was produced ?
Here is the WSDL I wrote first :
<?xml version="1.0" encoding="utf-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:rp="http://ws.csf.fr/ImmoService"
targetNamespace="http://ws.csf.fr/ImmoService">
<types>
...
</types>
<!-- =========================================================================
Messages
========================================================================= -->
<message name="imprimerDocumentsSoapIn">
<part name="parameters" element="rp:imprimerDocuments"/>
</message>
<message name="imprimerDocumentsSoapOut">
<part name="parameters" element="rp:imprimerDocumentsResponse"/>
</message>
<!-- =========================================================================
PortType
========================================================================= -->
<portType name="ImmoServiceSoap">
<operation name="imprimerDocuments">
<input message="rp:imprimerDocumentsSoapIn"/>
<output message="rp:imprimerDocumentsSoapOut"/>
</operation>
</portType>
<!-- =========================================================================
Binding
========================================================================= -->
<binding name="ImmoServiceSoap" type="rp:ImmoServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="imprimerDocuments">
...
</operation>
</binding>
<!-- =========================================================================
Service
========================================================================= -->
<service name="ImmoService">
<port name="ImmoServiceSoap" binding="rp:ImmoServiceSoap">
<soap:address location="http://serveur:0/ImmoService/webservices/ImmoService"/>
</port>
</service>
</definitions>
Here is the one I get when invoking my WS under Tomee with the ?wsdl parameter
<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.immoservice.csf.fr/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http" xmlns:ns1="http://ws.csf.fr/ImmoService" name="ImmoServiceService" targetNamespace="http://ws.immoservice.csf.fr/">
<wsdl:import location="http://vir-ws-int.csf.asso.fr:8080/ImmoService/webservices/ImmoService?wsdl=ImmoServiceSoap.wsdl" namespace="http://ws.csf.fr/ImmoService">
</wsdl:import>
<wsdl:binding name="ImmoServiceServiceSoapBinding" type="ns1:ImmoServiceSoap">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="imprimerDocuments">
<soap:operation soapAction="http://csf.fr/ImmoService/imprimerDocuments" style="document"/>
<wsdl:input name="imprimerDocuments">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="imprimerDocumentsResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ImmoServiceService">
<wsdl:port binding="tns:ImmoServiceServiceSoapBinding" name="ImmoServicePort">
<soap:address location="http://vir-ws-int.csf.asso.fr:8080/ImmoService/webservices/ImmoService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Here is the WSDL I get when I invoke my WS under Glassfish :
<?xml version='1.0' encoding='UTF-8'?>
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is Metro/2.3 (tags/2.3-7528; 2013-04-29T19:34:10+0000) JAXWS-RI/2.2.8 JAXWS/2.2 svn-revision#unknown. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is Metro/2.3 (tags/2.3-7528; 2013-04-29T19:34:10+0000) JAXWS-RI/2.2.8 JAXWS/2.2 svn-revision#unknown. -->
<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://ws.immoservice.csf.fr/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://ws.immoservice.csf.fr/" name="ImmoServiceService">
<import namespace="http://ws.csf.fr/ImmoService" location="http://localhost:8081/ImmoServiceService/ImmoService?wsdl=1"/>
<binding xmlns:ns1="http://ws.csf.fr/ImmoService" name="ImmoServicePortBinding" type="ns1:ImmoServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="imprimerDocuments">
<soap:operation soapAction="http://csf.fr/ImmoService/imprimerDocuments"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="ImmoServiceService">
<port name="ImmoServicePort" binding="tns:ImmoServicePortBinding">
<soap:address location="http://localhost:8081/ImmoServiceService/ImmoService"/>
</port>
</service>
</definitions>
This is the normal behavior of Java SOAP Frameworks (Metro, CXF). They always create a different WSDL even if you wrote a WSDL by hand, generated Code using wsimport and then fetch the generated WSDL using ?wsdl. Some frameworks allow you to provide your own WSDL when exposing the Service (see http://cxf.apache.org/docs/jax-ws-configuration.html Param wsdlLocation)
If you have a self-written WSDL, use it to generate Clients and Services using your WSDL. Do not use the generated one (That's my experience). You can reference the generated WSDL for having an always valid Endpoint but not for more.
I've to provide a .jsp page(index.jsp) along with my Web Service project for testing purpose.
Basically the .jsp page has a textarea, for reading a soap request as a string & on submitting it the soap response will come.
I tried it with "javax.xml.ws.Service & Dispatch" class, it's working fine.
But now I'm asked for a javascript/ajax based code.
Can anybody help me regarding this.
I'm giving a sample .wsdl file here :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://zensar.com/greeting" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Greeting"
xmlns:grtng="http://zensar.com/greeting/schema"
targetNamespace="http://zensar.com/greeting">
<wsdl:types>
<xsd:schema targetNamespace="http://zensar.com/greeting">
<xsd:import namespace="http://zensar.com/greeting/schema"
schemaLocation="Greeting.xsd"></xsd:import>
</xsd:schema>
</wsdl:types>
<wsdl:message name="GreetingRequest">
<wsdl:part element="grtng:GreetingRequest" name="GreetingRequest" />
</wsdl:message>
<wsdl:message name="GreetingResponse">
<wsdl:part element="grtng:GreetingResponse" name="GreetingResponse" />
</wsdl:message>
<wsdl:portType name="GreetingPort">
<wsdl:operation name="Greeting">
<wsdl:input message="tns:GreetingRequest" />
<wsdl:output message="tns:GreetingResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Greeting" type="tns:GreetingPort">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Greeting">
<soap:operation soapAction="http://zensar.com/GreetingWS/Greeting" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Greeting">
<wsdl:port binding="tns:Greeting" name="Greeting">
<soap:address location="http://localhost:8085/Greeting/services" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>**
Personally, I'd say consuming the web service directly through javascript is a bit masochistic.
In my opinion it'd be much easier for the javascript to call a server side method (with whatever architecture that may be, c#, java, php etc) then do a CURL request and send the response back to the front end.
Writing out a soap endpoint by hand in javascript just seems pointless when you could use something like Axis2 at the server side to do the boiler plate heavy loading of the SOAP handshake.
You can try this ... http://www.ibm.com/developerworks/webservices/library/ws-wsajax/
This article explains everything in detail.