Web technologies/2014-2015/Laboratory 12
Web Services
[edit | edit source]A Web Service (WS) is a software designed for to support inter-operable machine-to-machine interaction.
Usually a WS is exposed via an interface called a Web Service Description Language (WSDL). Based on this file a client is generated which is than used to invoke the actual service.
WSs and clients can be written in any language including Java, .NET languages, C, Python, etc.
Communication between clients and WSs is done through SOAP (Simple Object Access Protocol) which is an XML language serialized over HTTP.
A SOAP message is presented in what follows:
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<searchServices xmlns="urn:searchServices">
<pInput>
<procName>grayscale</procName>
<paramType>inIMG_1</paramType>
</pInput>
<pOutput>
<paramType>outIMG_1</paramType>
</pOutput>
</searchServices>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Every SOAP message has a header (</SOAP-ENV:Header>) and a body (<SOAP-ENV:Body>), both of which are placed inside an envelope (</SOAP-ENV:Envelope>). The header can be used to store information related with security and information about the message itself while the body of the message contains the actual XML that will be transmitted.
WSs can be invoked by using:
- Remote Procedure Calls
- Service Oriented Architecture (SOA) concepts
- Representational State Transfer (REST) - WSDL 2.0 (June 2007) allows a better integration with REST as it supports bindings for all the HTTP methods not just GET or POST.
NOTE: WSDL 1.1 is still widely used.
A typical WSDL 1.1 that performs operations using plain SOAP messages looks as follows:
<wsdl:definitions targetNamespace="http://services.eo.info.uvt.ro:8080/axis/services/gisheoSearchService">
<!--WSDL created by Apache Axis version: 1.4 Built on Apr 22, 2006 (06:55:48 PDT)-->
<!-- The Abstract data types -->
<wsdl:types>
<schema targetNamespace="http://ws.proc.gisheo">
<element name="searchServices" type="xsd:anyType"/>
</schema>
<schema targetNamespace="http://services.eo.info.uvt.ro:8080/axis/services/gisheoSearchService">
<element name="searchServicesReturn" type="xsd:anyType"/>
</schema>
</wsdl:types>
<!-- Abstract messages -->
<wsdl:message name="searchServicesRequest">
<wsdl:part element="tns1:searchServices" name="part"/>
</wsdl:message>
<wsdl:message name="searchServicesResponse">
<wsdl:part element="impl:searchServicesReturn" name="searchServicesReturn"/>
</wsdl:message>
<!-- Abstract interfaces -->
<wsdl:portType name="searchService">
<wsdl:operation name="searchServices">
<wsdl:input message="impl:searchServicesRequest" name="searchServicesRequest"/>
<wsdl:output message="impl:searchServicesResponse" name="searchServicesResponse"/>
</wsdl:operation>
</wsdl:portType>
<!-- Concrete binding with SOAP -->
<wsdl:binding name="gisheoSearchServiceSoapBinding" type="impl:searchService">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="searchServices">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="searchServicesRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="searchServicesResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<!-- Service endpoint for its binding -->
<wsdl:service name="searchServiceService">
<wsdl:port binding="impl:gisheoSearchServiceSoapBinding" name="gisheoSearchService">
<wsdlsoap:address location="http://services.eo.info.uvt.ro:8080/axis/services/gisheoSearchService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
The main tags inside a WSDL allow the following:
- types - contains the data types used by the service. They are encoded using an XML Schema
- message - contains information needed to perform a specific operation. One ore more parts can be placed inside a message. Parts are a description of the logical content of a message
- portType - defines a WS, the operations that can be performed, and the messages that are used to perform the operation\
- binding - specifies the interface, defines the SOAP binding style (RPC/Document) and transport (SOAP Protocol). It also defines the operations
- service - specifies the container service. It contains a collection of funtions exposed to the general public
- port - defines the address or connection point to a web service using its URL
NOTE: Some tags have been renamed in version 2.0: PortType → Interface, Message → N.A. (has been removed), Port → Endpoint.
NOTE: version 2.0 added further semantics to the description language and eliminated operator overloading.
NOTE: The hierarchy inside a WSDL 1.1 can be seen as follows: service-port → binding → portType-operation:input/output → message → types
Creating a WS
[edit | edit source]WSs can be created in two ways:
- bottom-up - create first the classes and then generate the WSDL bindings (easier)
- top-down - create the WSDL and then the classes (recommended)
NOTE: In Eclipse, WS can be created in the following ways:
- for the bottom-up approach: first create a Java bean or EJB bean and then use the Web services wizard to create the WSDL file and Web service
- for the top-down approach: first design the implementation of the Web service by creating a WSDL file (using the WSDL Editor). Then use the Web services wizard to create the Web service and skeleton Java classes to which the required code can be added
NOTE: NetBeans also allows you to create WSs. Simply follow this tutorial.
IMPORTANT In order to deploy WSs Apache Axis (1.0/2.0) needs to be installed. There are some differences between the versions and in what follows we will use the 1.0 version as basis:
Using JWSs
[edit | edit source]Java Web Service (JWS) files allow instant deployment of WSs.
NOTE: They should be used only for simple WSs.
Deploying the WS
[edit | edit source]To deploy a Java WS using JWS follow the next steps:
- create a Java class with public methods that you would like the clients to call. Call it for example simpleWS.java
- rename the Java file from simpleWS.java to simpleWS.jws
- copy the resulting JWS file to the $CATALINA_HOME/webapps
- restart the Tomcat container
- enter http://localhost/8080/simpleWS.jws?WSDL . If you see a WSDL file then the deployment was successful. Otherwise you may need to debug your Java code or check the file path in Tomcat.
The following code show how the simpleWS.java might look like. The add method will be the method called by clients to add to numbers they choose as input.
public class simpleWS {
public int add(int nr1, int nr2) {
return nr1 + nr2;
}
}
Calling the WS
[edit | edit source]To call the WS you can use one of the following:
- generate the SOAP request by hand (eg. by using DOM) and send the request;
- use the GET method to send the request. (REST-full approach);
- use RPC (Remote-Procedure-Call);
- generate the client stubs by using Axis tools;
- etc.
The RPC solution could look as follows:
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import javax.xml.rpc.ParameterMode;
public class TestSimpleWS {
public static void main(String [] args) {
try {
// Set the URL of the WS
String endpoint = "http://localhost:8080/simpleWS";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
// Set the SOAP Action URI if existing
call.setSOAPActionURI("http://the-soap-action-uri");
// Select the operation we would like to perform
call.setOperationName("add");
// Set the input parameters
call.addParameter("nr1", XMLType.XSD_INT, ParameterMode.IN);
call.addParameter("nr2", XMLType.XSD_INT, ParameterMode.IN);
// Set the return type
call.setReturnType(XMLType.XSD_INT);
// Call the service
Integer sum = (Integer) call.invoke( new Object[] { 3 , 2 } );
// Print the response
System.out.println("Sent 2+3. The sum is: " + sum);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Using WSDD
[edit | edit source]The Web Service Deployment Descriptor (WSDD) allows clients to easily deploy WSs without needing to transform them in a JWS file. This method is preferred when creating complex WSs.
Usually two WSDDs are created: one for deployment called deploy.wsdd and one for undeployment called undeploy.wsdd:
- deploy.wsdd:
<deployment name="SimpleWS" xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="simpleWS" style="message">
<parameter name="className" value="simpleWS"/>
<parameter name="allowedMethods" value="add"/>
<parameter name="scope" value="application"/>
</service>
</deployment>
- undeploy.wsdd:
<undeployment name="SimpleWS" xmlns="http://xml.apache.org/axis/wsdd/">
<service name="simpleWS"/>
</undeployment>
WSDD files allow clients to specify among others: the class they want to deploy as a WS, the methods they want to expose or the scope of the WS.
After the two WSDDs have been created the WS can be:
- deployed - be using: java org.apache.axis.client.AdminClient -hlocalhost -p8080 deploy.wsdd. The service will be automatically deployed and you can invoke it as in the JWS case
- undeployed - by using: java org.apache.axis.client.AdminClient -hlocalhost -p8080 undeploy.wsdd
NOTE: Axis allows user to also build their WSDL directly from Java classes (the java2wsdl command line tool) or to generate the stubs, skeletons and data types from the WSDL (the wsdl2java command line tool)
Links:
Publishing your WS
[edit | edit source]WSs can be published (made available to general public) by registering them to an Universal Description Discovery and Integration (UDDI) service
Links:
- Public WS Repository - allows users to publish their WS generate SOAP clients for them, etc.
- .NET WSs - offers a set of .NET WS to be used by client websites or applications.
Exercises
[edit | edit source]- Create a simple JSP page which queries a Weather Service (You can find details on the methods and arguments for an already published .NET WS at: http://www.webservicex.net/ws/WSDetails.aspx?CATID=12&WSID=56) and displays an image depending on the current weather data (you can display images similar to those used by the Windows Vista/7). The page should be HTML 4.01 Strict valid
- You can user either HTTP GET/POST or SOAP to retrieve the information, but HTTP GET/POST will only give you 3/4 of the total points for this exercise
- Create a simple WS that mimics the behaviour of a pocket calculator. Add the following operations: add, substract, divide, multiply, x to the power of y, square root. Deploy the WS and create a JSP page that invokes these methods. Each method will be invoked using a custom form. The page should be HTML 4.01 Strict valid