Why SOAP?
There are some great advantages which SOAP provides such as, SOAP can
make use of any transport protocol not just HTTP/HTTPS. When security and
reliability is a concern then you would need SOAP. SOAP security is well
standardized through WS-SECURITY. SOAP supports transactions and complies with
ACID phenomenon; it is reliable channel when you need transaction support.
What is SOAP?
SOAP stands for Simple Object Access Protocol. It is a XML based
communication medium/protocol. At the core it is an extension of HTTP protocol
which uses XML for sending and receiving messages/information.
As we know that web services are platform and language independent,
SOAP is used to create web services. SOAP is the XML way of defining what
information is sent and how. The definition of soap messages are done in WSDL
file which stands for web service definition language. We define endpoints,
request and response message definition using WSDL.
There are two versions/standards of SOAP. SOAP 1.1 (SOAP 11 Binding)
and SOAP 1.2 (SOAP 12 Binding). Both are W3C standards.
Homework:
- Find the difference between SOAP 1.1 and SOAP 1.2
- Does SOAP use GET or POST?
SOAP can be used in multiple ways of messaging systems such as RPC,
RMI, CORBA, DCOM etc. All of these messaging frameworks can work with SOAP. But
mainly SOAP is used with RPC.
A SOAP message is an XML document with the
following elements −
Ø
Envelope (Mandatory) – Used to define the start
and the end of the message.
Ø
Header (Optional) − Contains a header
information.
Ø
Body (Mandatory) − Contains the XML data which
is being sent.
Ø
Fault (Optional) − It provides information
about any error that occurs while processing the message.
Example:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:web="http://webservice.abhinavmishra14.github.com">
<soapenv:Header/>
<soapenv:Body>
<web:authenticateUser>
<web:user>admin</web:user>
<web:password>admin</web:password>
</web:authenticateUser>
</soapenv:Body>
</soapenv:Envelope>
|
Homework: Read about SOAP
xml elements in detail.
WSDL: It stands for web
service definition language. WSDL describes how to access a web service and
what operations it will perform. WSDL is an integral part of Universal
Description, Discovery, and Integration (UDDI). UDDI is a worldwide Webservice
registry. WSDL is the language that UDDI uses.
The three major elements of WSDL that can be defined separately are:
- Types
- Operations
- Binding
A WSDL document has various elements, but they are contained within
these three main elements, which can be developed as separate documents and
then they can be combined or reused to form complete WSDL files.
WSDL Elements:
A WSDL document contains the following elements:
Definitions: It is the root
element of WSDL. It defines the name of the web service, declares namespaces,
and contains all the service elements definitions.
Types: The data types to be
used in the soap messages are actually XML schemas (W3C Standard).
Message: It is used to
define the request and response messages which are used as part of services.
PortType: It is a collection
of operations mapped to service methods; it is used as a type for multiple
bindings.
Operation: It is the
abstract definition of the operation for a message, such as naming a method,
message queue, or business process, that will accept and process the message.
Binding: It is the concrete
protocol and data formats for the operations and messages defined for a
particular port type.
Service: It is a collection
of related end-points; the services map the binding to the port.
Port: It is a combination of
a binding and a network address. It is used to configure the target address of service.
Documentation: This element
is used to provide documentation.
Import: This element is used
to import another WSDLs or XML Schemas.
Visit for more details: https://www.w3.org/TR/wsdl
Example of WSDL:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:ns1="http://org.apache.axis2/xsd"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:abhi="http://webservice.abhinavmishra14.github.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
targetNamespace="http://webservice.abhinavmishra14.github.com">
<wsdl:types>
<xs:schema
attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="http://webservice.abhinavmishra14.github.com">
<xs:element
name="authenticateUser">
<xs:complexType>
<xs:sequence>
<xs:element
minOccurs="0" name="user" nillable="true"
type="xs:string"/>
<xs:element
minOccurs="0" name="password" nillable="true"
type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element
name="authenticateUserResponse">
<xs:complexType>
<xs:sequence>
<xs:element
minOccurs="0" name="return" nillable="true"
type="xs:anyType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message
name="authenticateUserRequest">
<wsdl:part
name="parameters" element="abhi:authenticateUser"/>
</wsdl:message>
<wsdl:message
name="authenticateUserResponse">
<wsdl:part
name="parameters"
element="abhi:authenticateUserResponse"/>
</wsdl:message>
<wsdl:portType
name="MyWebservicesPortType">
<wsdl:operation
name="authenticateUser">
<wsdl:input
message="abhi:authenticateUserRequest"
wsaw:Action="urn:authenticateUser"/>
<wsdl:output
message="abhi:authenticateUserResponse"
wsaw:Action="urn:authenticateUserResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding
name="MyWebservicesHttpBinding"
type="abhi:MyWebservicesPortType">
<http:binding
verb="POST"/>
<wsdl:operation
name="authenticateUser">
<http:operation
location="authenticateUser"/>
<wsdl:input>
<mime:content
type="application/xml" part="parameters"/>
</wsdl:input>
<wsdl:output>
<mime:content
type="application/xml" part="parameters"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service
name="MyWebservices">
<wsdl:port
name="MyWebservicesHttpEndpoint"
binding="abhi:MyWebservicesHttpBinding">
<http:address
location="http://127.0.0.1:8082/mywebservices/services/MyWebservices"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
|
Homework:
- Explore more about WSDL
- What is UUDI?
SOAP Services can be implemented
using two approaches:
- POJO based
- RAW XML based
Prerequisites:
- Create a web project using maven "maven-archetype-j2ee-simple" archetype.
- Add following dependencies in the pom file.
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-http</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-local</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
|
- Create services.xml under WEB-INF/services/<ServiceClassName>/META-INF folder.
- Visit Axis2 Configs for configuring the services.xml
Note: I am using Axis2 1.6.3 version for demo.
POJO based request and
response for SOAP messages:
Follow the below given steps to create a POJO based service:
- Define a Service class. E.g. MyWebservices
public
class MyWebservices {
}
|
//To receive the username and password from request
public class UserModel implements Serializable{
private static
final long serialVersionUID = -3529671170359212999L;
private String
userName;
private String
password;
public String
getUserName() {
return
userName;
}
public void
setUserName(final String userName) {
this.userName
= userName;
}
public String
getPassword() {
return
password;
}
public void
setPassword(final String password) {
this.password
= password;
}
}
//To return the response.
public class AuthResult implements Serializable{
private static
final long serialVersionUID = 3869694084982552728L;
private String
sessionId;
private String
responseMessage;
public String
getSessionId() {
return
sessionId;
}
public void
setSessionId(final String sessionId) {
this.sessionId
= sessionId;
}
public String
getResponseMessage() {
return
responseMessage;
}
public void
setResponseMessage(final String responseMessage) {
this.responseMessage
= responseMessage;
}
}
|
public class MyWebservices {
public AuthResult
authenticateUserPojo(final UserModel userModel){
final
String userName = userModel.getUserName();
final
String pass = userModel.getPassword();
final
AuthResult authResult = new AuthResult();
if(“admin”.equals(userName)
&& “admin”.equals(pass)) {
authResult.setResponseMessage(“Success”);
authResult.setSessionId("123xyz");
}
else {
authResult.setResponseMessage(“Failure”);
}
return
authResult;
}
}
|
<serviceGroup>
<service name="MyWebservices"
targetNamespace="http://webservice.abhinavmishra14.github.com">
.....
....
<operation
name="authenticateUserPojo">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"
/>
</operation>
……
</service>
</serviceGroup>
|
- Generate the WSDL using java2wsdl tool (can be found in axis2 bundle) or write wsdl manually.
- Build a war file and deploy to application server.
- Use the wsdl file and create a SOAP UI Project for testing the services or generate client code using wsdl2java tool (can be found in axis2 bundle).
Home work:
1-
Explore about the type of message receivers
2-
Explore service configuration
RAW XML based request and
response for SOAP messages:
Before start trying RAW xml based approach, let’s know a little bit
about AXIOM.
AXIOM stands for Axis Object Model and refers to the XML model that is
developed for Apache Axis2. It is a library within Axis2 framework which is
used to deal with XML infoset. XML infoset refers to the information included
inside the XML.
Key Features
- Full XML Infoset compliant XML object model
- STAX based builders with on-demand building and pull-through
- XOP/MTOM support offering direct binary support
- Convenient SOAP Infoset API on top of Axiom
- Two implementations included (GET, POST)
- Linked list based implementation
- W3C DOM supporting implementation
- Highly performant
Visit here for detailed information on AXIOM: https://ws.apache.org/axiom/userguide/ch02.html
Know how to create an XML object model: https://ws.apache.org/axiom/userguide/ch02.html#list2
Know how to create an XML object model by parsing an XML file: https://ws.apache.org/axiom/userguide/ch02.html#list1
Know about OMElement (a key class used for preparing XML object model):
https://ws.apache.org/axiom/apidocs/org/apache/axiom/om/OMElement.html
Follow the below given steps to create a RAW based service:
public
class MyWebservices {
}
|
public class MyWebservices {
public OMElement
authenticateUser(final String userName, final String password) {
final OMElement result =
messageFactory.createOMElement("resultOfAuthentication", null);
final OMElement responseMessage =
messageFactory.createOMElement("responseMessage",
null);
if("admin".equals(userName)
&& "admin".equals(password)) {
responseMessage.setText("Success");
final OMElement sessionId = messageFactory.createOMElement("sessionId",
null);
sessionId.setText("123abc");
result.addChild(sessionId);
} else {
responseMessage.setText("Failure");
}
result.addChild(responseMessage);
return result;
}
}
|
<serviceGroup>
<service name="MyWebservices"
targetNamespace="http://webservice.abhinavmishra14.github.com">
.....
....
<operation name="authenticateUser">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"
/>
</operation>
……
</service>
</serviceGroup>
|
- Generate the WSDL using java2wsdl tool (can be found in axis2 bundle) or write wsdl manually.
- Build a war file and deploy to application server.
- Use the wsdl file and create a SOAP UI Project for testing the services or generate client code using wsdl2java tool (can be found in axis2 bundle).
Home work:
Recommendation: It is recommended to always use the latest stable version of Axis2 framework. Current stable version is 1.6.3.
You can refer to the demo project @ my GitHub repository:
References:
1- https://axis.apache.org/axis2/java/core/docs/quickstartguide.html
2- http://axis.apache.org/axis2/c/core/docs/
1- https://axis.apache.org/axis2/java/core/docs/quickstartguide.html
2- http://axis.apache.org/axis2/c/core/docs/