Chapter 9 .
Creating Web Services :
Web services promises to be the next generation of software development. In essence, a web service is a means of interfacing to web or enterprise applications that allows you to integrate these with other enterprise applications, including those from different vendors and different platforms, using XML as the means of exchanging data.
There is a great deal of hype about web services. In the past there have been a number of initiatives to provide such vendor-and-platform agnostic integration technology, but none of these has been totally succesful. A good example is that of getting an enterprise applicaction running on Windows to communicate with an enterprise application running on Unix. Sure, it's been possible by various means but typically with a mechanism which is not equally well supported by both environments. That has changed with the advent of web services SOAP and XML provide an integration glue that everyone can finally agree on.
The basic mechanism of Web services is to use XML to transport its across different applications using the standard Web HTTP protocol (Hyper Text Transfer Protocol ). Specifically SOAP (Simple Object Access Protocol) is used, which is a lightweight XML based RPC (Remote Procedure Call) over HTTP. The protocol has three parts :
An envelope (SOAP envelope) that defines a framework for describing what is in a message and how to process it.
A set of encoding rules for expressing instances of application defined-dataypes.
A set of rules for representing remote procedure calls and responses.
Web Services Standards :
Now lets go through some evolving standards used in in Web Services, which are SOAP, WSDL (Web Services Description Language), UDDI (Universal Description Discovery and Integration), ebXML which is promoted by OASIS (Organization for the Advancement of Structured Information Standards) and UN/CEFACT (United Nations Centre for Trade Facilitation and Electronic Business). We will cover only SOAP and WSDL in this tutorial.
WSDL (Web Services Description Language) describes the interface of a network service similar to IDL (Interface Definition Language) in CORBA (Common Object Request Broker Architecture), specifying what messages an endpoint (i.e. a service instance which processes client requests and returns responses) will receive and send. WSDL is itself an XML metadata format. (In the terms of similar mechanisms like RMI or CORBA, a service is the interface or set of methods that a client will invoke across the wire).
SOAP (Simple Object Access Protocol) as discussed earlier describes the format of the data that is transmitted over the wire.
Both these standards are still evolving under the eye of the W3C, but these standards are regarded as the building block of the next revolution in distributed computing and the IT industry in general. Web services promise to do for machine-to-machine communication what the Web has done for human-to-human and machine-to-human communication.
However, due to the evolving nature of the web services standards together with the various related tools and platforms, the full impact is still far from being realized.
Web Services In Java :
As discussed earlier, Web Services standards are still evolving and their support in Java is still evolving. Even though Web Services were initially promoted by Microsoft and IBM, with the release of J2EE 1.4 Sun has provided full support for Web Services.
In the J2EE environment Web services are built on JAX-RPC (Java API for XML-based RPC). This is an API for building Web services and clients that use remote procedure calls (RPC) and XML.
In JAX-RPC, a remote procedure call is represented by an XML-based protocol such as SOAP. The SOAP specification defines the envelope structure, encoding rules, and convention for representing remote procedure calls and responses. These calls and responses are transmitted as SOAP messages (XML files) over HTTP. Even though the SOAP messages are a bit complex, but this complexity is transparent to the developer. When developing client and server side implementations, developers don't have to generate SOAP messages these are generated by the JAX-RPC API calls.
On the server side, the developer specifies the remote procedures by defining methods in an interface written in the Java programming language. The developer also codes one or more classes that implement those methods. Client programs are also easy to code. A client creates a proxy, a local object representing the service, and then simply invokes methods on the proxy. With JAX-RPC, the developer does not generate or parse SOAP messages. It is the JAX-RPC runtime system that converts the API calls and responses to and from SOAP messages.
For this tutorial, we will use the Apache Axis library, which is an open source initiative of the Apache Software Foundation (ASF). Axis is a JAX-RPC compliant SOAP engine. It can be integrated with web containers like Tomcat/Jetty, which allows it to use the features of such web containers like security, resource pooling, multi-threading, etc.
Note: JAX-RPC is based on JSR-101, which took the first step in defining a standard set of Java APIs and a programming model for developing and deploying Web services on the Java platform. Apache Axis is JAX-RPC compliant.
Now another specification which is evolving is JSR-109. This builds upon JAX-RPC. It defines a standard mechanism for deploying a Web service in the J2EE environment, more specifically, in the area of Enterprise JavaBean (EJB) technology and servlet containers.
Both of these specifications will be integrated into the J2EE 1.4 specification. Together they serve as the basis of Web services for J2EE.
Jboss.3.2.x comes with integrated support for Web-services provided by Jboss.Net. Jboss.NET has Apache AXIS as a plugin service for the Jboss-Microkernel. Jboss.Net uses the built-in JBoss deployment system that understands the WSR packaging. [Web Service aRchive (WSR- or .wsr-) files are ordinary .jar files that contain, besides necessary byte code for plugging into the Axis machinery, a slightly extended Axis deployment descriptor in their "META-INF/web-service.xml" entry]. Currently, there are not that many application servers available which support WSR deployment, which can result in portability issues.
Therefore for this tutorial we will use Apache-AXIS 1.1 for creating and deploying web services.
Installing AXIS :
Download the Apache-Axis binary from http://ws.apache.org/axis/.
Ex : Version 1.1 Binary - tar.gz
First create a dir named axis under /opt and then save this file under /opt/axis/.
- [vishal@vishal axis]$ pwd
- /opt/axis
- [vishal@vishal axis]$ ls
- axis-1_1.tar.gz
Now unzip the file. A new directory will be created with the name axis-1_1.
- [vishal@vishal axis]$ tar -xvzf axis-1_1.tar.gz
- axis-1_1/
- axis-1_1/docs/
- axis-1_1/docs/ant/
- axis-1_1/docs/ant/ant.html
- axis-1_1/docs/ant/axis-admin.html
- -----------------------------------------------------
- ----------------------------------------------------
- ------------------------------------------------------
- axis-1_1/xmls/
- axis-1_1/xmls/checkstyle.xml
- axis-1_1/xmls/deploy_catalina_local.xml
- axis-1_1/xmls/path_refs.xml
- axis-1_1/xmls/properties.xml
- axis-1_1/xmls/targets.xml
- axis-1_1/xmls/taskdefs.xml
- axis-1_1/xmls/taskdefs_post_compile.xml.
- [vishal@vishal axis]$ ls
- axis-1_1 axis-1_1.tar.gz
- [vishal@vishal axis]$
-
The directory structure will be as shown below.
- [vishal@vishal axis]$ pwd
- /opt/axis
- [vishal@vishal axis]$ ls
- axis-1_1 axis-1_1.tar.gz
- [vishal@vishal axis]$ cd axis-1_1
-
- [vishal@vishal axis-1_1]$ ls
- docs lib LICENSE README release-notes.html samples webapps xmls
-
- [vishal@vishal axis-1_1]$ pwd
- /opt/axis/axis-1_1
-
- [vishal@vishal axis-1_1]$ cd lib/
-
- [vishal@vishal lib]$ ls
- axis-ant.jar commons-discovery.jar jaxrpc.jar saaj.jar
- axis.jar commons-logging.jar log4j-1.2.8.jar wsdl4j.jar
- [vishal@vishal lib]$
Now the axis binary is installed, let's configure it for use with our application server Jboss-3.2.1.
Configuring AXIS with JBOSS :
In order to configure Jboss with Axis, first go to $JBOSS_HOME/server/all/deploy/all/ as shown below.
- [vishal@vishal deploy]$ pwd
- /opt/jboss/jboss-3.2.1/server/all/deploy
- [vishal@vishal deploy]$
-
Create a dir named webapps under this directory as shown below.
- [vishal@vishal deploy]$ ls
- cache-invalidation-service.xml jbossweb-jetty.sar MyStoreMgr.jar
- cluster-service.xml jboss-xa-jdbc.rar OnlineStore.war
- farm-service.xml jms properties-service.xml
- hsqldb-ds.xml jmx-console.war schedule-manager-service.xml
- http-invoker.sar jmx-ejb-connector-server.sar scheduler-service.xml
- iiop-service.xml jmx-invoker-adaptor-server.sar sqlexception-service.xml
- jbossha-httpsession.sar jmx-rmi-adaptor.sar transaction-service.xml
- jboss-jca.sar mail-service.xml user-service.xml
- jboss-local-jdbc.rar management uuid-key-generator.sar
- jboss-net.sar MyFirstBean.jar
- jbossweb-ejb.jar MySecondBean.jar
-
- [vishal@vishal deploy]$ mkdir webapps
-
- [vishal@vishal deploy]$ ls
- cache-invalidation-service.xml jbossweb-jetty.sar MyStoreMgr.jar
- cluster-service.xml jboss-xa-jdbc.rar OnlineStore.war
- farm-service.xml jms properties-service.xml
- hsqldb-ds.xml jmx-console.war schedule-manager-service.xml
- http-invoker.sar jmx-ejb-connector-server.sar scheduler-service.xml
- iiop-service.xml jmx-invoker-adaptor-server.sar sqlexception-service.xml
- jbossha-httpsession.sar jmx-rmi-adaptor.sar transaction-service.xml
- jboss-jca.sar mail-service.xml user-service.xml
- jboss-local-jdbc.rar management uuid-key-generator.sar
- jboss-net.sar MyFirstBean.jar webapps
- jbossweb-ejb.jar MySecondBean.jar
- [vishal@vishal deploy]$
-
Now go to /opt/axis/axis-1_1/webapps dir. Copy the axis dir to $JBOSS_HOME/server/all/deploy/all/webapps/ as shown below.
Note : Here JBOSS_HOME is /opt/jboss/jboss-3.2.1
- [vishal@vishal webapps]$ pwd
- /opt/axis/axis-1_1/webapps
- [vishal@vishal webapps]$ ls
- axis
- [vishal@vishal webapps]$ cp -r axis /opt/jboss/jboss-3.2.1/server/all/deploy/webapps/.
- [vishal@vishal webapps]$
-
Now go back to the $JBOSS_HOME/server/all/deploy/webapps/ dir and rename the axis directory to axis.war.
- [vishal@vishal webapps]$ pwd
- /opt/jboss/jboss-3.2.1/server/all/deploy/webapps
- [vishal@vishal webapps]$ ls
- axis
- [vishal@vishal webapps]$ mv axis axis.war
- [vishal@vishal webapps]$ ls
- axis.war
- [vishal@vishal webapps]$
-
Note : As shown above, the directory axis has been renamed to axis.war so that JBOSS can recognize this as a web application and hence the web container can deploy it at run-time.
Now from within Eclipse start your Application server (JBOSS) , if it isn't already running. If it is already running then don't restart it as it will hot-deploy the the axis.war.
Also make sure all the libraries which come with AXIS are on the classpath ($CLASSPATH or $AXISCLASSPATH) as shown below.
- [ vishal@vishal lib]$ pwd
- /opt/jboss/jboss-3.2.1/server/all/deploy/webapps/axis.war/WEB-INF/lib
- [vishal@vishal lib]$ ls
- axis-ant.jar commons-discovery.jar jaxrpc.jar saaj.jar
- axis.jar commons-logging.jar log4j-1.2.8.jar wsdl4j.jar
- [vishal@vishal lib]$ echo $AXISCLASSPATH
- /opt/axis/axis-1_1/lib/axis.jar:/opt/axis/axis-1_1/lib/jaxrpc.jar:/opt/axis/axis-1_1/lib/saaj.jar:/opt/axis/axis-1_1/lib/wsdl4j.jar:/opt/axis/axis-1_1/lib/commons-discovery.jar:/opt/axis/axis-1_1/lib/commons-logging.jar:.
- [vishal@vishal lib]$
-
-
Now to test your configuration go to http://127.0.0.1:8080/axis/.
Note : The port no. will be different if you have customized it from its default settings.
You should now be able to see an Apache-Axis start page as shown below. If you do not, then either the webapp is not actually installed properly, or the appserver is not running.
Now Validate the local installation's configuration by clicking on the link 'Validate the local installation's configuration'.
This will bring you to happyaxis.jsp, a test page that verifies whether required and optional libraries are present. The URL for this will be something like http://localhost:8080/axis/happyaxis.jsp as shown below in figure.
If any of the needed libraries are missing, Axis will not work.
Note : Make sure that all the needed libraries are found, and this validation page is happy.
Optional components are indeed optional; install them as you require. If you see nothing but an internal server error and an exception trace, then you probably have multiple XML parsers on the CLASSPATH (or AXISCLASSPATH), and this is causing version confusion.
Now go back to your Apache AXIS start page and select the list of already deployed Web services. By clicking on 'View the list of deployed Web services'.
Note : There are a few web services which come with Apache-AXIS bundle to assist us with our learning curve.
In order to make sure that your Web Service is up and running, click on each WSDL (Web Service Description Language) as shown above in figure. Example : If we click on AdminService (WSDL) then the following screen will be available as shown below.
Before we write our first Web Service, let's test one of the working example services which is already deployed as part of the Apache bundle.
Note : For more information look at the documentation for Apache-AXIS under 'Installing and deploying web applications using xml-axis' at http://ws.apache.org/axis/.
Now, SOAP 1.1 uses HTTP POST to submit an XML request to the endpoint, but Axis also supports a HTTP GET access mechanism, which is very useful for useful for testing. So to test the service, let's retrieve the version of Axis from the version endpoint, by calling the getVersion
method:
http://localhost:8080/axis/services/Version?method=getVersion
This will result in the screen shown below.
After successfully testing the Web Service, let's write our own first Web Service by extending our tutorial application MyStore.
We will create a web service named MyStoreLoginService, which will allow the user to login to MyStore using a Java Client, but using Web service (HTTP) rather then RMI, which is normally the case when we use servlets/JSP or a Java Client. StoreAccessBean will be acting as our endpoint.
Note : Lomboz-2.1_02 witth Eclipse 2.1 and Lomboz 2.1.1 with Eclipse 2.1.1 doesn't have a wizard to create a webservice (that is Web Service Deployment Descriptor [WSDD]) and deploy it. So we will have to do it by hand. Both versions of Lomboz do provide a wizard for creating a SOAP Client.
![](http://www.tusc.com.au/tutorial/images/chap9/ApacheAXISIntegration.png)
Create the Web Service :
In order to create a Web Service we need to create an endpoint. In this case, our Stateless Bean StoreAccessBean will be acting as an endpoint. Method loginUser will be invoked from the client side using this Web Service, so we have to create a Web Service Deployment Descriptor (WSDD) file describing the signature of the loginUser method along with some other required information.
Note : Currently, only a Stateless Bean can be used as an endpoint for a Web Service as specified in JSR-109.
WSDD is an AXIS specific file, used to create a skeleton for JAX-RPC. This is transparent to the developer, and once this skeleton is created and deployed, AXIS generates WSDL and publishes the Web-Service.
For more information : http://ws.apache.org/axis/.
Now, under Eclipse, go to Package Explorer > Expand Mystore (project) node > select src, right click and a menu will pop up.
On the pop up menu > New > Select Package > Add name of package as 'au.com.tusc.WebService' .
Press Finish.
This will create a new package named au.com.tusc.WebService under 'src'.
Go to src/au.com.tusc.WebService > Select New > File as shown below.
Now create a file named deploy.wsdd under the package au.com.tusc.WebService as shown below.
Add the following XML tags as shown below in the deploy.wsdd file, and then we will examine the contents of the file..
Lets analyze these deployment descriptors.
<service name="MyStoreLoginService" provider="java:EJB">
The service name tag is responsible for giving the name to the service and the provider. Provider states that the web service is an EJB-Web Service. The name of our service is MyStoreLoginService and the provider is java:EJB .
<parameter name="beanJndiName" value="StoreAccessLocal"/>
The first parameter is beanJndiName which specifies where the bean (EJB) is in the JNDI tree.
We are using the local interfaces of StoreAccessBean, so it is StoreAccessLocal.
Note : We used non-local interfaces for StoreAccessBean until chapter 8, where the Bean is accessed by Web Components and Java Clients. As all the component are in the same JVM, we are typically using local interfaces as these interfaces have many advantages compared to remote interfaces. These are:
Simpler programming model, no need to catch remote exceptions that can't happen in co-located deployment.
Since RemoteException is not needed on every method signature, your EJB business method's interface is independent of EJB. This can free callers from dependence on the EJB API.
As it is running in the same JVM and not in a distributed environment, although coded to call-by-value it is running with call-by-reference.
<parameter name="homeInterfaceName" value="au.com.tusc.session.StoreAccessLocalHome"/>
The parameter above is called homeInterfaceName and it has as it's value the Remote Home Local Interface which is au.com.tusc.session.StoreAccessLocalHome.
<parameter name="remoteInterfaceName" value="au.com.tusc.session.StoreAccessLocal"/>
The parameter above is called remoteInterfaceName and it has as it's value the Remote Local Interface which is au.com.tusc.session.StoreAccessLocal.
<parameter name="allowedMethods" value="loginUser"/>
The allowedMethods parameter has the value loginUser to indicate that only this method will be made public or can be accesed from client. The rest of the parameters are specific to the application server, in this case JBOSS.
So, now our deploy.wsdd is complete, let's deploy it.
Note : Currently Lomboz doesn't have a wizard for creating the WSDD file and to deploy it. So that's why we have to create it by hand.
Deploy the Web Service :
In order to deploy this we will have to go to our Linux console (If windows then DOS-console).
Now, assuming the application server (JBOSS) is running and our bean has bean deployed (All the beans are in MyStore.jar as covered in previous chapters).
Go into the directory where deploy.wsdd has been created as shown below.
- [vishal@vishal WebService]$ pwd
- /home/vishal/workspace/MyStore/src/au/com/tusc/WebService
- [vishal@vishal WebService]$ ls
- deploy.wsdd
- [vishal@vishal WebService]$
Note : Make sure that $AXISCLASSPATH is set properly as mentioned above.
- [vishal@vishal WebService]$ echo $AXISCLASSPATH
/opt/axis/axis-1_1/lib/axis.jar:/opt/axis/axis-1_1/lib/jaxrpc.jar:/opt/axis/axis-1_1/lib/saaj.jar: /opt/axis/axis- 1_1/lib/wsdl4j.jar:/opt/axis/axis-1_1/lib/commons-discovery.jar: /opt/axis/axis-1_1/lib/commons-logging.jar:.
- [vishal@vishal WebService]$
Now we will be using the AdminClient ( org.apache.axis.client.AdminClient) class,which is part of the AXIS API's, to deploy the WSDD.
Note : By default it uses port 8080, but if you have to use different port number then use the -p <port> argument.
Use this command to deploy WSDD as shown below.
- [vishal@vishal WebService]$ java org.apache.axis.client.AdminClient deploy.wsdd
- Processing file deploy.wsdd
- <Admin>Done processing</Admin>
- [vishal@vishal WebService]$
If the message shown above is displayed then your web service is deployed succesfully.
Note : An admin client can be used both from the command line and programmatically.
Now, let's access our web service and its corresponding Web Service Description Language (WSDL).
Go to the following URL http://localhost:8080/axis/servlet/AxisServlet to see the all the deployed services as shown below.
Go to wsdl and it will show the WSDL generated by AXIS for the deployed Web Service as shown below.
Now save this WSDL as it will be required to generate the SOAP Client using Lomboz's SOAP Client creation wizard. Save this file under the package au.com.tusc.WebService as shown below.
Note : The Lomboz SOAP client wizard uses the "WSDL2Java" tool, which will build Java proxies and skeletons for services with WSDL descriptions. This tool comes with the Apache-AXIS distribution.
Now go back to Eclipse, and refresh your project. MyStore and MyStoreLoginService.wsdl will be present now as shown below.
Since the Web Service is deployed successfully it's time to create the test client.
Create Web Service Test Client :
Now, Lomboz (Both versions 2.1_02 & 2.1.1) provides a wizard for Creating SOAP clients for published web services using their corresponding WSDL files.
But before we do that, one necessary step is to make sure we have all the libraries on the classpath neccesary for generateing the stub for the SOAP Client. These are the same libraries used for $AXISCLASSPATH covered above in the chapter.
Note : This can be configured by adding the neccessary libraries to the jboss321all.server file used for configuration of Lomboz with Eclipse, which was covered in chapter 1.
To import the required libraries on the projects classpath,
Go to Project Explorer select project MyStore > right click > select properties.
Under Properties > select Java Build Path > select tab Libraries.
Press Add External jars as shown below.
The following libraries are imported as shown below:
axis.jar, jaxrpc.jar, saaj.jar, wsdl4j.jar, commons-discovery.jar, commons-logging.jar
Note : Lomboz 2.1_02 and 2.1.1 come with the libraries mentioned. Since we are using the latest version of Apache-AXIS (V1.1), it is better to import these new libraries instead.
Now under Project Explorer go to src/au.com.tusc.WebService> right click.
On the pop up menu select New > select Lomboz SOAP client Wizard.
Under the SOAP Client Wizard select 'MyStoreLoginService.wsdl'. Also select the checkbox with Add Axis to buildpath. And under namespace mapping select the package name 'au.com.tusc.WebService' as shown below in figure.
Press Finish.
This will create the stub for the client comprising four files under au.com.tusc.WebService as shown below.
Now let's write the test client.
So, Go to src/au.com.tusc.WebService and add a new file named TestClient.java.
Add the following code to this (TestClient.java) file as shown below. We will analyze this code later.
Now let's examine the 2 main statements.
StoreAccessLocalServiceLocator service = new StoreAccessLocalServiceLocator();
This is necessary as the ServiceLocator object returns the endpoint for the web service which is used for making the call. In this example the end point is "http://localhost:8080/axis/services/MyStoreLoginService";
StoreAccessLocal port = service.getMyStoreLoginService();
This returns the reference of the local interface for the bean so that the necessary methods can be invoked.
Note : There are four different styles of service in Axis 1.1 as specified in the user guide that comes with the Apache-AXIS distribution.
RPC services use the SOAP RPC conventions, and also the SOAP "section 5" encoding. The test client which we have created above is using SOAP RPC style.
Document services do not use any encoding (so in particular, you won't see multiref object serialization or SOAP-style arrays on the wire) but DO still do XML<->Java databinding.
Wrapped services are just like document services, except that rather than binding the entire SOAP body into one big structure, they "unwrap" it into individual parameters. The web clients covered later on are using this style of service.
Message services receive and return arbitrary XML in the SOAP Envelope without any type mapping / data binding. If you want to work with the raw XML of the incoming and outgoing SOAP Envelopes, write a message service.
For more information please refer to the use guide.
Test your Client :
To test your client, select au.com.tusc.WebService.TestClient node > Go to the top level menu and select the 'Running Man' icon.
On that select 'Run as' > select Java Application.
Note : The steps to run test clients have been covered in previous chapters.
Now, under your console, If you get UserID as as 'U2' then your call was successful, as shown below.
We have learned how to create, deploy and access web services using a Java client. Now that same web service can be accessed using web components like servlets (JSP/Servlets).
There are three different ways of creating web service clients which are
Using the Static Stub Client implemented in the client example discussed above.
Dynamic Proxy Client.
Dynamic Invocation Interface (DII) Client used in the Web client implemented in next section.
Create Web Client :
To create a web client all the necessary steps have been covered in chapter 8, so leaving those details, we can straight away add the following lines to our servlet named 'Login' under au.com.tusc.WebService as shown below in this code snippet from Login.java.
package au.com.tusc.WebService; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.namespace.QName; import org.apache.axis.client.Call; import org.apache.axis.client.Service; /** * @author vishal * * To change the template for this generated type comment go to * Window>Preferences>Java>Code Generation>Code and Comments */ public class Login extends HttpServlet { public void init(ServletConfig config) throws ServletException { super.init(config); System.out.println("Entering Login.init()") ; System.out.println("Leaving Login.init()") ; } protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } protected void processRequest (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("Entering Login.processRequest()"); response.setContentType("text/html"); PrintWriter out = response.getWriter (); out.println("<html><title>MyStore Login</title>"); out.println("<body><b><h2>Welcome to MyStore </h2></b></body>"); out.print("<body><h2>Login details : UserID is : "); try { String username = callWebService(); out.print(username); } catch (Exception e) { System.out.println("Exception in Login.processRequest "); } out.print("</h2></body></html>"); if ( out != null ) out.close(); System.out.println("Leaving Login.processRequest()"); } private String callWebService() throws Exception { // URL is used for creating the call, which uses the WSDL. Call call = new Call( new URL("http://localhost:8080/axis/services/MyStoreLoginService?wsdl") ); // Calls the object, passing in the username and passwd. The return value is stored as an object. String username = (String) call.invoke ("loginUser", new Object[] { new String("ANDY") , new String("PASSWD") } ); return username; } }
Note : Another way of invoking the loginUser method is to use Axis' JAXRPC Dynamic Invocation Interface implementation of the Service interface. The Service class should be used as the starting point for accessing SOAP Web Services. Typically, a Service will be created with a WSDL document, and along with a serviceName you can then ask for a Call object that will allow you to invoke the Web Service. Shown below is the other way of implementing the callWebService() method. Both versions of callWebService() method use the DII approach.
private String callWebService() throws Exception { // Endpoint is used for making the call String endpoint = "http://localhost:8080/axis/services/MyStoreLoginService"; // The Service object is the starting point for accessing the web service. Service service = new Service(); // The call object is used to actually invoke the web service. Call call = (Call)service.createCall(); // Sets the call objects endpoint address call.setTargetEndpointAddress(endpoint); // Sets the operation name associated with this Call object. call.setOperationName(new QName("loginUser")); // Calls the object, passing in the username and passwd. The return value is stored as an object. Object returnValue = call.invoke(new Object[] { new String("ANDY") , new String("PASSWD") }); return (String) returnValue; }
Note: The difference between the two approaches is that the Call interface provides support for the dynamic invocation of a service endpoint whereas the Service class acts as a factory for the Dynamic proxy for the target service endpoint.
Also shown below is web.xml where the servlet's access name and its mapping are shown.
Note : The steps to create a servlet are covered in chapter 8. Servlet Login is included in the OnlineStore web module.
Now once you have completed the servlet, deploy the web module OnlineStore. If there are no error messages in the console then the web module has been deployed succesfully.
Note : The steps are covered in chapter 8 on how to deploy web modules.
To invoke the login method on the published web service go to this url http://localhost:8080/OnlineStore/login.
If you get the following screen shown below then your call is succesfull.
Until now we have seen how to access web services using web clients and Java clients from the same environment. Now to really experience the amazing power of Web Services we will invoke this web service using a .NET (Microsoft Client).
Create VB.Net Client :
Now, to create a VB.Net client create a new Windows Application Project for Visual Basic.NET named DOTNETCLIENT as shown below in the figure.
Click on OK.
Change the form name property to DOTNETCLIENT.
Add the following controls to the form with the following properties as shown below in the figure.
Label Control Name: lblName Text: Name Label Control Name: lblPassword Text: Password Label Control Name: lblResult Text: Result Label Control Name: lblOutput Text: TextBox Control Name: TextBoxName Text: TextBox Control Name: TextBoxPassword Text: PasswordChar: * Button Control Name: btnGetID Text: Get ID
Now, add the Web Reference of the Web Services to the Project.
Right-click on the DOTNETCLIENT from the Solution Explorer and click on Add Web Reference as shown below.
Add the following URL of the Web Service, which is the location of the published web service. http://xxx.yyy.zzz.aaa:8080/axis/services/MyStoreLoginService?wsdl.
Note : This URL is pointing to the machine where the web service is published.
Click on GO - as shown below in the figure it will show the service with its method(s) available under it.
Click on the Add Reference button as shown above.
This will bring a new screen with Web Reference added to the project via Solution Explorer as shown below.
Now, double click the button GetID on the form editor to view the code as shown below in the figure.
Add the following code for the Sub btnGetID_Click().
Dim strResult As String 'Output result for ID Dim objWebRef As New WebReference.StoreAccessLocalService 'Call loginuser function and display the result ID to the lblOutput control lblOutput.Text = objWebRef.loginUser(TextBoxName.Text, TextBoxPassword.Text)
Once you have added the code, go to the top level menu, select Build > select Build Solution as shown above in the figure.
Now, start the application and you will get this form shown below. Enter Name as 'ANDY' and Password as 'PASSWD' . Press the GetID button and the Result should be 'U2'.
Now with this we have successfully run a .NET client accessing our web services
Create Perl Client :
To create a Perl client we need the SOAP::Lite module to invoke methods on deployed web services.
First of all download the latest version of SOAP::Lite and follow the standard Perl module installation procedures by entering the very familiar command sequence:
- perl Makefile.PL
- make
- make test
- make install
-
If you have the CPAN.pm module installed on your machine and you are connected to the Internet, then run the following sequence of commands as shown below:
- [vishal@vishal vishal]$ perl -MCPAN -e shell
- cpan shell -- CPAN exploration and modules installation (v1.61)
- ReadLine support available (try 'install Bundle::CPAN')
- cpan> install SOAP::Lite
- CPAN: Storable loaded ok
- CPAN: LWP::UserAgent loaded ok
- Fetching with LWP:
- ftp://mirror.aarnet.edu.au/pub/perl/CPAN/authors/01mailrc.txt.gz
- Going to read y/sources/authors/01mailrc.txt.gz
- CPAN: Compress::Zlib loaded ok
- Fetching with LWP:
- ---------------------------------------------
- ---------------------------------------------
- ---------------------------------------------
- CPAN: Digest::MD5 loaded ok
- Fetching with LWP:
- ftp://mirror.aarnet.edu.au/pub/perl/CPAN/authors/id/K/KU/KULCHENKO/CHECKSUMS
- Checksum for y/sources/authors/id/K/KU/KULCHENKO/SOAP-Lite-0.55.tar.gz ok
-
- cpan> bye
- Lockfile removed.
- [vishal@vishal vishal]$
-
- If you are using ActiveState Perl on Windows the equivalent would be the 'ppm' command.
Note : For more information on the SOAP::Lite module please refer to this site http://www.soaplite.com/beta/install.html.
Now let's create a Perl client to invoke the logInUser method on the deployed web service named MyStoreLoginService.
Create a file named webServiceClient.pl and add the following code shown below.
- #
- # WebServiceClient.pl
- #
- # Test client for MyStoreLoginService Web service
- # Apache Axis - Chapter 9 'Creating Web Services'
- #
- use SOAP::Lite ;
-
- my $myStoreLoginService = SOAP::Lite->service('http://localhost:8080/axis/services/MyStoreLoginService?wsdl');
- my $username = $myStoreLoginService->loginUser("ANDY","PASSWD");
- print "MyStore login details : Andy's username is : $username /n";
-
-
Save this file, and execute it to see the result shown below.
- [vishal@vishal vishal]$ perl WebServiceClient.pl
- MyStore login details : Andy's username is : U2
- [vishal@vishal vishal]$
-
Now with this we have successfully run a Perl client accessing the web service.