Java calculator via web services. With Axis 1.4, build both server and client sides of a web service. Complete source code included.
Web services are a handy method of integrating independent systems. Apache Axis is one of the best free tools available for implementing and deploying web services, and also for implementing the web service clients. In this article we will create a simple, but complete web service and a client for this service step-by-step. Article will be explanatory as much as possible to succeed you in implementing it yourself alone after completing this tutorial.
JDK installation
These examples have been tested on a machine with JDK 1.6 version.
Web Server
You must have a web server installed; and we will be using Tomcat (5.5 version) web server. If you are not having one, better download Tomcat here{link} and install it yourself (it is quite easy to install Tomcat). Now your CATALINA_HOME environment variable should point to the Tomcat installation directory.
Apache Axis 1.4
Download Apache Axis 1.4. Extract the downloaded file and you’ll find a folder named “axis” inside webapps folder.
%Axis_1.4_dir%\webapps\axis
Copy this “axis” folder into your web server’s webapps folder.
%CATALINA_HOME%\webapps
CLASS PATH
Now you must add following libraries into your CLASSPATH environment variable. All of these are available under %Axis_1.4_dir%\lib folder.
[post_ads]
We'll compile above class using following command so that the generated .class file will reside in a folder named "classes" while preserving the package structure.
And compile using following command.
This command will generate a file named calculator.wsdl inside your project folder.
Generated java classes will be saved in org.kamal.wssample.ws.generated package. This tool will generate five Java classes in this case with two .wsdd files as listed below.
There is a class named CalculatorSoapBindingImpl inside org.kamal.wssample.ws.generated package. This is the class used to bind our existing SimpleCalculator class to the web service calls. In CalculatorSoapBindingImpl class, there are two methods; add() and subtract(). In this class, we can use the SimpleCalculator to call the actual methods as follows.
Just analyze the above class, all method calls are delegated to the actual implementation class SimpleCalculator inside this binding class.
Now copy this jar file into %CATALINA_HOME%\webapps\axis\WEB-INF\lib folder.
We will create another jar file to use in the client side. For the client side we only need the classes that were generated by the WSDL2java tool (which are located inside org\kamal\wssample\ws\generated package), except the CalculatorSoapBindingImpl class.
Note: (Tomcat) Server must be started before executing the following command.
This command will deploy the web service into axis. Now restart (Tomcat) server.
To verify our web service is deployed correctly; try following url from your browser.
http://localhost:8080/axis/services/calculator?wsdl
(change the port 8080 in url to match the port on your machine)
This will show up a complete wsdl file, and it is the complete definition of the web service that we have deployed.
Now everything on web service (server side) is completed and our web service is successfully deployed.
[post_ads_2]
For the client side we will create a new project folder named “WS-Client” with sub folders named src, classes and lib. Copy the generated calculatorClientSide.jar file into the "WS-Client\lib" folder.
We will create the client as follows. Since our web service exposed two methods, add() and subtract(); client class will use the service and call those add() and subtract() methods.
The above class has not used even a single class that we wrote for Calculator implementation, only a few classes that WSDL2Java tool generated. We have not exposed the server side classes, but just provided a way to get the service from those classes.
Compile the class with following command.
Now we can run our web service client using following command.
You would see the following as the result.
Our web service client, CalcClient has accessed the web service and received the results from the operations done by SimpleCalculator class (which is running on server side).
As you can see, generating the client side is much easier than the server side.
Prerequisites
- Must be familiar with Java
- Familiar with basics on a web server like Tomcat
- Some knowledge in configuring Axis will be an added advantage
System Configuration Requirements
We will be discussing the configuration in brief as our scope is mainly on web services. (If Axis already configured, jump to implementation). If you find any issues on the configuration part, you can refer to Apache Axis site for troubleshooting. (But if you can not solve it yourself do not worry, post the issue under the comments section in this article, and we’ll get back to you).JDK installation
These examples have been tested on a machine with JDK 1.6 version.
Web Server
You must have a web server installed; and we will be using Tomcat (5.5 version) web server. If you are not having one, better download Tomcat here{link} and install it yourself (it is quite easy to install Tomcat). Now your CATALINA_HOME environment variable should point to the Tomcat installation directory.
Apache Axis 1.4
Download Apache Axis 1.4. Extract the downloaded file and you’ll find a folder named “axis” inside webapps folder.
%Axis_1.4_dir%\webapps\axis
Copy this “axis” folder into your web server’s webapps folder.
%CATALINA_HOME%\webapps
CLASS PATH
Now you must add following libraries into your CLASSPATH environment variable. All of these are available under %Axis_1.4_dir%\lib folder.
- axis.jar
- commons-discovery.jar
- commons-logging.jar
- jaxrpc.jar
- log4j-1.2.8.jar
- saaj.jar
- wsdl4j.jar
[post_ads]
Implementation - web service and client
The implementation will consist of two parts. First we will implement web service part; a Calculator will be exposed as a web service. Next a client to use this Calculator web service will be implemented. (Client part starts from here).Calculator Web Service
Implementing the web service consists of 7 steps. We will be explaining each step in detail.- Functionality provider
- Web service’s interface
- Java2WSDL - Generate WSDL file
- WSDL2Java - Generate server side and client side classes for web service
- Bind Web service with Functionality provider
- Bundle required classes
- Register web service with axis
Project structure
Before starting coding, we'll have a look at the project structure. We are using a separate folder for the project, called "WS-Sample". We will be creating source (.java) files under "WS-Sample\src" folder and storing generated class (.class) files under a "WS-Sample\classes" folder.1. Functionality provider
First we need to write class with calculator functionality before exposing it as a web service. We have implemented it as a pretty complex high end calculator class, named SimpleCalculator and it's listed below. (It is just a pretty simple class with three methods). This class has no information related to a web service and has been written as a simple independent class. So in the time this class was written, no one has thought of any web service stuff. But we will expose this class as a web service. (Yes, what you guessed is correct. Later you can expose your existing Java classes as web services.)
package org.kamal.wssample;
public class SimpleCalculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
public int multiply(int a, int b) {
return a * b;
}
}
WS-Sample\src> javac -d ..\classes
org\kamal\wssample\SimpleCalculator.java
2. Web service’s interface
Now we should write an interface that defines the services that will be provided by our web service. We will expose only two methods through our service; add() and subtract() methods (although we can expose any number of services within one web service). We did choose only two methods to emphasize the fact that we can control which methods we expose. And we will write this class in a separate package; org.kamal.wssample.ws.
package org.kamal.wssample.ws;
public interface Calculator {
int add (int x, int y);
int subtract(int x, int y);
}
WS-Sample\src> javac -d ..\classes
org\kamal\wssample\ws\Calculator.java
3. Java2WSDL - Generate WSDL file
Axis has a tool called Java2WSDL, which generates a WSDL file for a web service using a Java class. We should use the Calculator interface and generate WSDL file as follows. Java2WSDL file requires the Calculator.class file (not Calculator.java) for the operation. Also we will provide the following information.- o – name for WSDL file -> calculator.wsdl
- n – target namespace -> urn:org.kamal.calculator
- l – url of web service -> http://localhost:8080/axis/services/calculator
WS-Sample\classes> java org.apache.axis.wsdl.Java2WSDL
-o ..\calculator.wsdl
-n urn:org.kamal.calculator
-l http://localhost:8080/axis/services/calculator
org.kamal.wssample.ws.Calculator
4. WSDL2Java - Generate server side and client side classes for web service
Axis has another tool named WSDL2Java, which can generate server side and client side Java classes using a WSDL file. These classes are needed for deploying the web service and for accessing the service by a Java client. This tool must be provided with WSDL file that we generated in the previous step. It needs the following information as well.- o – output folder -> src
- p – package for generated classes -> org.kamal.wssample.ws.generated
- s – generate server side classes as well
WS-Sample> java org.apache.axis.wsdl.WSDL2Java
-o src
-p org.kamal.wssample.ws.generated
-s
calculator.wsdl
- Calculator.java
- CalculatorService.java
- CalculatorServiceLocator.java
- CalculatorSoapBindingImpl.java
- CalculatorSoapBindingStub.java
- deploy.wsdd
- undeploy.wsdd
WS-Sample\src> javac –d ..\classes
org\kamal\wssample\ws\generated\*.java
5. Bind Web service with Functionality provider
As you may have noted; even though we wrote org.kamal.wssample.SimpleCalculator class at the start, we have not used it so far. Now we are going to bind it to the web service.There is a class named CalculatorSoapBindingImpl inside org.kamal.wssample.ws.generated package. This is the class used to bind our existing SimpleCalculator class to the web service calls. In CalculatorSoapBindingImpl class, there are two methods; add() and subtract(). In this class, we can use the SimpleCalculator to call the actual methods as follows.
package org.kamal.wssample.ws.generated;
import org.kamal.wssample.SimpleCalculator;
public class CalculatorSoapBindingImpl implements
org.kamal.wssample.ws.generated.Calculator {
private SimpleCalculator calc = new SimpleCalculator();
public int add(int a, int b) throws java.rmi.RemoteException {
return calc.add(a, b);
}
public int subtract(int from, int x) throws java.rmi.RemoteException {
return calc.subtract(from, x);
}
}
6. Bundle required classes
Now we will create a jar file with all these classes, so that we can use it for deploying our web service. Use the jar command as follows.
WS-Sample\classes> jar cvf ..\calculatorServerSide.jar
org\kamal\wssample\*.class
org\kamal\wssample\ws\*.class
org\kamal\wssample\ws\generated\*.class
WS-Sample> copy calculatorServerSide.jar
"%CATALINA_HOME%\webapps\axis\WEB-INF\lib"
We will create another jar file to use in the client side. For the client side we only need the classes that were generated by the WSDL2java tool (which are located inside org\kamal\wssample\ws\generated package), except the CalculatorSoapBindingImpl class.
WS-Sample\classes> jar cvf ..\calculatorClientSide.jar
org\kamal\wssample\ws\generated\CalculatorSoapBindingStub.class
org\kamal\wssample\ws\generated\CalculatorServiceLocator.class
org\kamal\wssample\ws\generated\CalculatorService.class
org\kamal\wssample\ws\generated\Calculator.class
7. Register web service with axis
Axis comes with a tool for registering web services with Axis; it is called AdminClient. Look into org\kamal\wssample\ws\generated folder and you will find two WSDD (web service deployment descriptor) files; deploy.wsdd and undeploy.wsdd. These files were generated by WSDL2Java tool and as used in deploying/undeploying a web service.Note: (Tomcat) Server must be started before executing the following command.
WS-Sample\src> java org.apache.axis.client.AdminClient
org\kamal\wssample\ws\generated\deploy.wsdd
To verify our web service is deployed correctly; try following url from your browser.
http://localhost:8080/axis/services/calculator?wsdl
(change the port 8080 in url to match the port on your machine)
This will show up a complete wsdl file, and it is the complete definition of the web service that we have deployed.
Now everything on web service (server side) is completed and our web service is successfully deployed.
[post_ads_2]
Web Service client
Now it’s time for us to write a client to access this web service and use provided services. For this we need the calculatorClientSide.jar file that we created in an earlier step.For the client side we will create a new project folder named “WS-Client” with sub folders named src, classes and lib. Copy the generated calculatorClientSide.jar file into the "WS-Client\lib" folder.
We will create the client as follows. Since our web service exposed two methods, add() and subtract(); client class will use the service and call those add() and subtract() methods.
package org.kamal.wsclient;
import org.kamal.wssample.ws.generated.Calculator;
import org.kamal.wssample.ws.generated.CalculatorService;
import org.kamal.wssample.ws.generated.CalculatorServiceLocator;
public class CalcClient {
public static void main(String[] args) throws Exception {
CalculatorService service = new CalculatorServiceLocator();
Calculator calc = service.getcalculator();
System.out.println("15 + 6 = " + calc.add(15, 6));
System.out.println("15 - 6 = " + calc.subtract(15, 6));
}
}
Compile the class with following command.
WS-Sample-Client\src> javac -classpath %CLASSPATH%;..\lib\calculatorClientSide.jar
-d ..\classes
org\kamal\wsclient\CalcClient.java
WS-Sample-Client\classes> java -cp %CLASSPATH%;.;..\lib\calculatorClientSide.jar
org.kamal.wsclient.CalcClient
15 + 6 = 21
15 – 6 = 9
As you can see, generating the client side is much easier than the server side.
COMMENTS