Difference between a SOAP message and a WSDL? - java

I am confused about how SOAP messages and WSDL fit together? I have started looking into SOAP messages such as:
POST /InStock HTTP/1.1
Host: www.example.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.example.org/stock">
<m:GetStockPrice>
<m:StockName>IBM</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
Are all SOAP messages WSDL's? Is SOAP a protocol that accepts its own 'SOAP messages' or 'WSDL's? If they are different, then when should I use SOAP messages and when should I use WSDL's?
Some clarification around this would be awesome.

A SOAP document is sent per request. Say we were a book store, and had a remote server we queried to learn the current price of a particular book. Say we needed to pass the Book's title, number of pages and ISBN number to the server.
Whenever we wanted to know the price, we'd send a unique SOAP message. It'd look something like this;
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<m:GetBookPrice xmlns:m="http://namespaces.my-example-book-info.com">
<ISBN>978-0451524935</ISBN>
<Title>1984</Title>
<NumPages>328</NumPages>
</m:GetBookPrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
And we expect to get a SOAP response message back like;
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<m:GetBookPriceResponse xmlns:m="http://namespaces.my-example-book-info.com">
<CurrentPrice>8.99</CurrentPrice>
<Currency>USD</Currency>
</m:GetBookPriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The WSDL then describes how to handle/process this message when a server receives it. In our case, it describes what types the Title, NumPages & ISBN would be, whether we should expect a response from the GetBookPrice message and what that response should look like.
The types would look like this;
<wsdl:types>
<!-- all type declarations are in a chunk of xsd -->
<xsd:schema targetNamespace="http://namespaces.my-example-book-info.com"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<xsd:element name="GetBookPrice">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ISBN" type="string"/>
<xsd:element name="Title" type="string"/>
<xsd:element name="NumPages" type="integer"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="GetBookPriceResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CurrentPrice" type="decimal" />
<xsd:element name="Currency" type="string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
But the WSDL also contains more information, about which functions link together to make operations, and what operations are avaliable in the service, and whereabouts on a network you can access the service/operations.
See also W3 Annotated WSDL Examples

A SOAP message is an XML document which is used to transmit your data. WSDL is an XML document which describes how to connect and make requests to your web service.
Basically SOAP messages are the data you transmit, WSDL tells you what you can do and how to make the calls.
A quick search in Google will yield many sources for additional reading (previous book link now dead, to combat this will put any new recommendations in comments)
Just noting your specific questions:
Are all SOAP messages WSDL's? No, they are not the same thing at all.
Is SOAP a protocol that accepts its own 'SOAP messages' or 'WSDL's? No - reading required as this is far off.
If they are different, then when should I use SOAP messages and when should I use WSDL's? Soap is structure you apply to your message/data for transfer. WSDLs are used only to determine how to make calls to the service in the first place. Often this is a one time thing when you first add code to make a call to a particular webservice.

We need to define what is a web service before telling what are the difference between the SOAP and WSDL where the two (SOAP and WSDL) are components of a web service
Most applications are developed to interact with users, the user enters or searches for data through an interface and the application then responds to the user's input.
A Web service does more or less the same thing except that a Web service application communicates only from machine to machine or application to application. There is often no direct user interaction.
A Web service basically is a collection of open protocols that is used to exchange data between applications. The use of open protocols enables Web services to be platform independent. Software that are written in different programming languages and that run on different platforms can use Web services to exchange data over computer networks such as the Internet. In other words, Windows applications can talk to PHP, Java and Perl applications and many others, which in normal circumstances would not be possible.
How Do Web Services Work?
Because different applications are written in different programming languages, they often cannot communicate with each other. A Web service enables this communication by using a combination of open protocols and standards, chiefly XML, SOAP and WSDL. A Web service uses XML to tag data, SOAP to transfer a message and finally WSDL to describe the availability of services. Let's take a look at these three main components of a Web service application.
Simple Object Access Protocol (SOAP)
The Simple Object Access Protocol or SOAP is a protocol for sending and receiving messages between applications without confronting interoperability issues (interoperability meaning the platform that a Web service is running on becomes irrelevant). Another protocol that has a similar function is HTTP. It is used to access Web pages or to surf the Net. HTTP ensures that you do not have to worry about what kind of Web server -- whether Apache or IIS or any other -- serves you the pages you are viewing or whether the pages you view were created in ASP.NET or HTML.
Because SOAP is used both for requesting and responding, its contents vary slightly depending on its purpose.
Below is an example of a SOAP request and response message
SOAP Request:
POST /InStock HTTP/1.1
Host: www.bookshop.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.bookshop.org/prices">
<m:GetBookPrice>
<m:BookName>The Fleamarket</m:BookName>
</m:GetBookPrice>
</soap:Body>
</soap:Envelope>
SOAP Response:
POST /InStock HTTP/1.1
Host: www.bookshop.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.bookshop.org/prices">
<m:GetBookPriceResponse>
<m: Price>10.95</m: Price>
</m:GetBookPriceResponse>
</soap:Body>
</soap:Envelope>
Although both messages look the same, they carry out different methods. For instance looking at the above examples you can see that the requesting message uses the GetBookPrice method to get the book price. The response is carried out by the GetBookPriceResponse method, which is going to be the message that you as the "requestor" will see. You can also see that the messages are composed using XML.
Web Services Description Language or WSDL
WSDL is a document that describes a Web service and also tells you how to access and use its methods.
WSDL takes care of how do you know what methods are available in a Web service that you stumble across on the Internet.
Take a look at a sample WSDL file:
<?xml version="1.0" encoding="UTF-8"?>
<definitions name ="DayOfWeek"
targetNamespace="http://www.roguewave.com/soapworx/examples/DayOfWeek.wsdl"
xmlns:tns="http://www.roguewave.com/soapworx/examples/DayOfWeek.wsdl"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<message name="DayOfWeekInput">
<part name="date" type="xsd:date"/>
</message>
<message name="DayOfWeekResponse">
<part name="dayOfWeek" type="xsd:string"/>
</message>
<portType name="DayOfWeekPortType">
<operation name="GetDayOfWeek">
<input message="tns:DayOfWeekInput"/>
<output message="tns:DayOfWeekResponse"/>
</operation>
</portType>
<binding name="DayOfWeekBinding" type="tns:DayOfWeekPortType">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="GetDayOfWeek">
<soap:operation soapAction="getdayofweek"/>
<input>
<soap:body use="encoded"
namespace="http://www.roguewave.com/soapworx/examples"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body use="encoded"
namespace="http://www.roguewave.com/soapworx/examples"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding>
<service name="DayOfWeekService" >
<documentation>
Returns the day-of-week name for a given date
</documentation>
<port name="DayOfWeekPort" binding="tns:DayOfWeekBinding">
<soap:address location="http://localhost:8090/dayofweek/DayOfWeek"/>
</port>
</service>
</definitions>
The main things to remember about a WSDL file are that it provides you with:
A description of a Web service
The methods a Web service uses and the parameters that it takes
A way to locate Web services

A WSDL (Web Service Definition Language) is a meta-data file that describes the web service.
Things like operation name, parameters etc.
The soap messages are the actual payloads

Better analogy than the telephone call: Ordering products via postal mail from a mail-order service.
The WSDL document is like the instructions that explain how to create the kind of order forms that the service provider will accept.
A SOAP message is like an envelope with a standard design (size, shape, construction) that every post office around the world knows how to handle. You put your order form into such an envelope. The network (e.g. the internet) is the postal service. You put your envelope into the mail. The employees of the postal service do not look inside the envelope.
The payload XML is the order form that you have enclosed in the envelope. After the post office delivers the envelope, the web service provider opens the envelope and processes the order form. If you have created and filled out the form correctly, they will mail the product that you ordered back to you.

In a simple terms if you have a web service of calculator. WSDL tells about the functions that you can implement or exposed to the client. For example: add, delete, subtract and so on. Where as using SOAP you actually perform actions like doDelete(), doSubtract(), doAdd(). So SOAP and WSDL are apples and oranges. We should not compare them. They both have their own different functionality.

SOAP :
It's an open standard XML based Communication protocol which is used to exchange information from the user to web service or vice versa.
The soap is just the document in which the data are organized in some Manner.
For every request and response separate soap may be present.
WSDL:
In soap the data are organized in some manner and this organization is specified in WSDL, The data type which has to be used are also specified here.
For request and response single WSDL will be present

WSDL act as an interface between sender and receiver.
SOAP message is request and response in xml format.
comparing with java RMI
WSDL is the interface class
SOAP message is marshaled request and response message.

The WSDL is a kind of contract between API provider and the client it's describe the web service : the public function , optional/required field ...
But The soap message is a data transferred between client and provider (payload)

We can consider a telephone call In that Number is wsdl and exchange of information is soap.
WSDL is description how to connect with communication server.SOAP is have communication messages.

Related

How to implement digital signature validation in spring web service for different clients?

I have a requirement to validate the digital signature of the SOAP request using X509 certificates for a spring based webservice that accepts requests from multiple vendors.
What is the general strategy for implementing such a security? Should I create one webservice for each vendor so that I can validate the digital signature based on the public key of the caller? Ideally I would like to just have one webservice as the content of each vendor request has the same schema.
The digital signature for SOAP messages is embedded into the SOAP header of the message. This is a simplified schema of a message. (See a full example here)
<?xml version="1.0" encoding="UTF8"?>
<SOAP-ENV:Envelope>
<SOAP-ENV:Header>
<wsse:Security
<wsse:BinarySecurityToken />
<ds:Signature>
<ds:SignedInfo>
<ds:SignatureValue>
<ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The signature allows to know the identity of the signer referencing the x509 certificate used to sign.
You do not need different webservice for each vendor. To allow access, request the public part of the certificate to the vendor that is going to be used to sign messages. When a soap message is received, compare the signer certificate with the expected one.
To simplify comparison, you can check serialnumber+issuer

Convert from 1 message format to another format

Here is my requirement.
I have a client that was sending a specific message format to some software service provider(ABC) using what ever network protocol.
Now this client is switching software service provider (XYZ) but does not want to change their software and wants to continue sending the same message of ABC provider.
Provider ABC uses some sort of positional based message format over some archaic network protocol
Provider XYZ uses XML over HTTP(s) web service not SOA just simple POST with XML
Some values can be directly mapped while others must be recalculated or modified. For instance converting client's account number from ABC Provider to account number of XYZ provider. this is for request and response.
The archaic network protocol will be converted to TCPI/IP at the network level so that is not an issue.
The client expect a response in real time. I.e: Client makes request, XYZ does what ever and response back to client.
So I need to create some sort of tunnel that accepts TCP/IP converts the message to XML, sends it HTTP(s) POST to XYZ, get back XML response, convert back to positional based, reply back through TCPI/IP to the client.
Is this an ESB type thing, should I just write some sort JAVA server app that will do this?
You have too many options. Starting from Python, Perl.. there are libraries/modules that provide your TCP/HTTP/telnet/... support. Using that you can do this.
ESB might be an overkill for this, it's a big framework for big integrations, but yes you can write your BCs (Binding Components) and do it. Performance I'm not sure if ESB would be as good as something more primitive like .pl/.py
In short there are too many options. You have to take the call based on the environment in which you have to deploy it.
E.g. you said "Some values can be directly mapped while others must be recalculated or modified. For instance converting client's account number from ABC Provider to account number of XYZ provider. this is for request and response.", if ABC-A/c-num to XYZ-A/c-num mapping is only available via a remote EJB call then you might want to consider writing the whole thing in J2EE. If you "calculations" need some specific libs you have to factor that in as well...
Hope this doesn't make your problem worse.. :)
PS: You should start accepting answers to your previous questions. as Home said.
Tried Mule ESB it's very light weight. I would say even more so then some of it's competition. I like how it's not particularly bound to SOA or soap. So you can construct any kind of end point from plain TCP/IP, HTTP, File, to Email to anything really it has more then a dozen connectors and you can even write your own. I also like the fact that the message can be anything. I could be wrong but even when others claim they have various connectors and message formats they seem to have SOAP somewhere hidden under the hood and it seems icky lol Some others seem good, but have poor docs. Didn't like the fact that some basic JDBC functionality is only available in the enterprise edition. I.e: To get Output parameters from your stored proc call you need the enterprise edition.
In reality I could have picked any server API that allowed me to create a server to receive HTTP, then write my code to transform a message, open a client connection to the next service send it off, receive the response, re-transform it back and return to the client. All while making sure threads and queues are behaving correctly within the server. Maybe I could have just used jetty and a servlet and do everything in one request. It's an option, but if I have to switch to TCP/IP then I just change the config a bit. Waiting to see what the client says.
The ESB is basically the glue and plumbing. All I had to do was write three custom transformer classes as the messages I deal with are proprietary banking formats and don't exactly map to simple XSLT/XML transforms... And about a 20 XML tags to put it all together...
This is all I needed to get this out of Mule (not including the tags to build my datasource and SQL query)...
<flow name="myFlow">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" />
<object-to-string-transformer />
<custom-transformer class="com.mycom.transformer.MyTransformer" />
<enricher target="#[variable:client]">
<jdbc:outbound-endpoint queryKey="getClientConfig" exchange-pattern="request-response" />
</enricher>
<custom-transformer class="com.MyCom.transformer.MyOtherTransformer" />
<http:outbound-endpoint exchange-pattern="request-response" host="xxx.xxx.xxx.xxx" port="80" path="some path" method="POST"/>
<custom-transformer class="com.MyCom.transformer.BackToOtherFormat" />
</flow>
So basically...
1- receive HTTP(s) with custom message
2- Parse message to get client number
3- Lookup client number in database to get client number for the other service...
4- Create the new message
5- Send off to other service
6- Transform response back
7- Return to client
<flow name="FileTransferFlow1" doc:name="FileTransferFlow1">
<file:inbound-endpoint path="C:\mule_projects\filetransfer\in" responseTimeout="10000" doc:name="IncomingFile"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP" responseTransformer-refs="Java"/>
<custom-transformer class="com.Transformer" doc:name="Java"/>
<file:outbound-endpoint path="C:\mule_projects\filetransfer\out" responseTimeout="10000" doc:name="OutgoingFile"/>
</flow>

PHP Session variables in java

In my server-client model I'm using java for client side and for server side scripting using php5.
For communication I'm using simple http protocol.
In server I have some $SESSION variables(in php). I want access these variables in my java client.
How can it be posssible?
Thanks in advance.
AFAIK session variables is a server-side variables, that can be accessed by session id. You must refactor you application (to make java-client free of server side information) or send them (variables) from server to client manually.
You should use cookies instead of session variables if you're planning on sending it to the client side.
Your Java-client will make requests to the server, and the server will act like a web service, right?
If so, include all/any $_SESSION variables you might need with the XML/json/whatever response that the server sends back to the clients, something along the lines of:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<reply>
<request>
<method>getUsers</method>
<param name="page">1</param>
<param name="apiKey">API_KEY</param>
<param name="sessId">SESSION_ID</param>
</request>
<response>
<status>
<code>0</code>
<message>OK</message>
</status>
<users>
<!-- Request reply here -->
</users>
<session>
<variable1>$_SESSION['var1']</variable1>
<!-- Additional session variables you might need on the client here[...] -->
</session>
</response>
</reply>
The thing is, session variables are something the server uses to keep track of which client is accessing it now, and relate data to that particular client. If you need this information on the client, perhaps you could refactor the application to create this data on the client and pass it to the server in case the server needs that data?
Simple.
<script type="text/javascript">
var variable = '<?php echo $SESSION["variable_name"];?>';
</script>
The only thing you have to understand is that session variables has no difference from any other PHP variable.
Thus, you have to request it from PHP as well.
Of course, supplying a request with session identifier got from the previous calls. That's all, not a rocket science.

Can a .NET 2.0 Web Service handle a call from a client when the SoapAction is missing?

We have a .NET 2.0 web service (.ASMX file). This web service is being called by a Java client and they are not passing in a SoapAction header.
This causes our web service to fail with the error: : "Server did not recognize the value of HTTP Header SOAPAction: ."
There is no chance that I can convince the development team in charge of the calling Java client to include a SoapAction header.
Is there anyway to resolve this problem on my end?
Can I prevent .NET from throwing this error when the SoapAction is missing? Can I direct the call to the correct WebMethod programmatically?
Something like this psuedo-code,
if (Header.SoapAction == String.Empty) then MyWebMethod();
According to the SOAP 1.1 specification this is required of HTTP clients.
6.1 SOAP HTTP Request
Although SOAP might be used in
combination with a variety of HTTP
request methods, this binding only
defines SOAP within HTTP POST requests
(see section 7 for how to use SOAP for
RPC and section 6.3 for how to use the
HTTP Extension Framework).
6.1.1 The SOAPAction HTTP Header Field
The SOAPAction HTTP request header
field can be used to indicate the
intent of the SOAP HTTP request. The
value is a URI identifying the intent.
SOAP places no restrictions on the
format or specificity of the URI or
that it is resolvable. An HTTP client
MUST use this header field when
issuing a SOAP HTTP Request.
Source http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528
From a quick Google it seems this is a common issue with Java and Axis, but there is some debate whether it is required. Could this help you convince the Java developers that they need to implement the header?
Edit:
The correct URI for your SoapAction http header is defined in the WSDL document.
Goto http://mydomain.com/myservice.asmx?wsdl
Look for the wsdl:operation element for the method you are calling, it should have a child element soap:operation which has a attribute called soapaction, the URI in there is the one you should use. In a webservice i tested it looks like the namespace followed by / and the method name as follows.
<wsdl:operation name="AddTwoNumbers">
<soap:operation soapAction="http://mydomain.com/myservice/AddTwoNumbers" style="document"/>

Microsoft SSRS consuming JAX-WS Web Service

I have developed a Web Service using JAX-WS (v2.1.3 - Sun JDK 1.6.0_05) that works just fine when I use a Java client or SoapUI or other Web Services testing tools. I need to consume this service using 2005 Microsoft SQL Server Reporting Services and I get the following error
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Client</faultcode>
<faultstring>Couldn't create SOAP message due to exception: XML reader error: unexpected character content:
"?"
</faultstring>
</S:Fault>
</S:Body>
</S:Envelope>
If I use a HTTP proxy to sniff out what SSRS is sending, I see EF BB BF as the beginning of the post body and JAX-WS doesn't like that. If I remove the special characters and resubmit the request using Fiddler, then the web-service invocation works.
My question is why does SSRS introduce these special characters and how can I make it stop? If I can't stop it, how can I get JAX-WS to ignore them? Here is my SSRS query:
<Query>
<Method Name="getOneUser" Namespace="http://vinny.com" >
</Method>
</Query>
I've also tried a query like this below:
<Query>
<Method Name="getOneUser" Namespace="http://vinny.com" >
</Method>
<SoapAction>http://vinny.com/getOneUser</SoapAction>
<ElementPath IgnoreNamespaces="true">*</ElementPath>
</Query>
Does anyone have any ideas on what I can try? I've tried several different types of annotations on the JAX-WS side to change the type of SOAPBinding, etc. but nothing seem to make it work with Microsoft SSRS.
The "Special characters" are the "Byte order marker" (BOM) indicating that the post body is UTF-8. http://unicode.org/faq/utf_bom.html#BOM
The Java service should be smart enough not to puke on these characters; I'm afraid I don't know how to help it.

Categories