Translate

Writing a simple web service and a client with Axis2

1. The service

Here a simple POJO service will be created. For simplicity the service will have only two operations.

1. Save an order which consists of an index(String) and a price(Double)
The order will be saved to an xml file.

2. Retrieve the price given the index.



First create a Java Project.

Now inside package orderprocessing.data I create the Order POJO.

package orderprocessing.data;
/**
* Created by manurip on 6/28/15.
*/
public class Order{
private double price;
private String index;
public Order(String index, double price){
this.index = index;
this.price = price;
}
public String getIndex(){
return index;
}
public double getPrice() {
return price;
}
}
view raw Order.java hosted with ❤ by GitHub
Inside the package orderprocessing.service I create OrderProcessingService Class.

package orderprocessing.service;
import orderprocessing.data.Order;
/**
* Created by manurip on 6/28/15.
*/
public class OrderProcessingService {
/*
* This is a test method
*/
public String sayHello() {
return "Hello";
}
public String addOrder(String index,Double price) {
Order newOrder = new Order(index,price);
XMLWriterDOM.getInstance().saveOrder(newOrder);
Order retrieved = XMLReaderDOM.getInstance().retrieveOrder(index);
if(retrieved!= null){
return "Added Order. Index:"+retrieved.getIndex()+" Price:"+retrieved.getPrice();
}
else{
return "Unable to add order";
}
}
public String getPrice(String index) {
String result = "NONE";
Order order = XMLReaderDOM.getInstance().retrieveOrder(index);
if(order!=null){
result = Double.toString(order.getPrice());
}
System.out.println("Price Retrived. Index=" + index
+ ", Price=" + result);
return result;
}
}
In order to save orders to an XML file I create XMLWriterDOM.java.
package orderprocessing.service;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import orderprocessing.data.Order;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class XMLWriterDOM {
private static XMLWriterDOM instance = null;
private final String retrievePath;
private XMLWriterDOM(){
retrievePath="/path/to/orders.xml";
}
public static XMLWriterDOM getInstance() {
if(instance == null){
instance= new XMLWriterDOM();
}
return instance;
}
public void saveOrder(Order order){
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
try {
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(retrievePath);
Element rootElement = doc.getDocumentElement();
rootElement.appendChild(getOrder(order, doc));
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult console = new StreamResult(System.out);
StreamResult file = new StreamResult(new File(retrievePath));
transformer.transform(source, console);
transformer.transform(source, file);
System.out.println("DONE");
} catch (Exception e) {
e.printStackTrace();
}
}
private Node getOrder(Order order,Document doc){
Element orderElement = doc.createElement("Order");
Element indexElement = doc.createElement("index");
indexElement.setTextContent(order.getIndex());
Element priceElement = doc.createElement("price");
priceElement.setTextContent(Double.toString(order.getPrice()));
orderElement.appendChild(indexElement);
orderElement.appendChild(priceElement);
return orderElement;
}
}
To retrieve orders from the XML file I create XMLReader.java
package orderprocessing.service;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import orderprocessing.data.Order;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XMLReaderDOM {
private static XMLReaderDOM instance = null;
private final String savePath;
private XMLReaderDOM(){
savePath="/path/to/orders.xml";
}
public static XMLReaderDOM getInstance() {
if(instance == null){
instance= new XMLReaderDOM();
}
return instance;
}
public Order retrieveOrder(String requiredIndex){
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
try {
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(savePath);
Element rootElement = doc.getDocumentElement();
NodeList orderList = rootElement.getElementsByTagName("Order");
System.out.println(orderList.getLength());
Node orderElement ;
NodeList children;
int counter;
double price = 0;
String index =null;
for(int i=0;i<orderList.getLength();i++){
orderElement = orderList.item(i);
children = orderElement.getChildNodes();
counter =0;
for(int j=0;j<children.getLength();j++ ){
if(children.item(j).getNodeType()==Node.ELEMENT_NODE){
if(counter==0){
index = children.item(j).getTextContent();
counter++;
}
else
price = Double.parseDouble(children.item(j).getTextContent());
}
}
if(requiredIndex.trim().equals(index)){
return new Order(requiredIndex,price);
}
}
System.out.println("DONE");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Create an XML file orders.xml somewhere and change the "savePath", and "retrievePath" attributes inside the above two classes according to that.


Now create a folder META-INF at the src folder level and create services.xml inside META-INF.
<?xml version="1.0" encoding="UTF-8"?>
<service name="OrderProcessingService">
<description>
Order Processing Service
</description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</messageReceivers>
<parameter name="ServiceClass">orderprocessing.service.OrderProcessingService
</parameter>
</service>
view raw services.xml hosted with ❤ by GitHub

Here, If you do not specify the message receiver, then the default message receiver which is RawXMLINOutMessageReceiver will perform the operation[1]

And since the service implementation class is in Java, all the public methods in that service will be exposed. No need to specifically include them in services.xml[1]


This is the folder structure of my service.


Now export the project as a jar. In eclipse this can be done by, right click on the project->export
Save it to somewhere and change it's extension to .aar (eg: if your jar is OrderProcessingService.jar rename it as OrderProcessingService.aar ) and save it to axis2-1.6.2/repository/services
(I am using axis2-1.6.2)

Start the axis2server. (In linux run axis2server.sh inside axis2-1.6.2/bin)



Now if you go to http://localhost:8080/axis2/services/ it should be shown as below.



And you can access the wsdl at, http://localhost:8080/axis2/services/OrderProcessingService?wsdl


2. The client

Create another Java project.

Now in order to use the service we need to create the stub.

Go to axis2-1.6.2/bin in the terminal and run,
sh wsdl2java.sh -uri http://localhost:8080/axis2/services/OrderProcessingService?wsdl -o /source/folder/of/client/project
view raw command.sh hosted with ❤ by GitHub
Now create another package orderprocessing.client inside your client project and create OrderProcessingClient.java

package orderprocessing.client;
import java.rmi.RemoteException;
import orderprocessing.service.OrderProcessingServiceStub;
import org.apache.axis2.AxisFault;
public class OrderProcessingClient {
private OrderProcessingServiceStub stub;
public OrderProcessingClient() throws AxisFault {
stub = new OrderProcessingServiceStub(
"http://localhost:8080/axis2/services/OrderProcessingService");
}
public String sayHello() throws Exception {
try {
OrderProcessingServiceStub.SayHello req = new OrderProcessingServiceStub.SayHello();
OrderProcessingServiceStub.SayHelloResponse res = stub
.sayHello(req);
return res.get_return();
} catch (RemoteException e) {
String msg = "Cannot say hello"
+ " . Backend service may be unavailable";
throw new Exception(msg, e);
}
}
public String addOrder(String index, double price) throws Exception {
try {
OrderProcessingServiceStub.AddOrder req = new OrderProcessingServiceStub.AddOrder();
req.setIndex(index);
req.setPrice(price);
OrderProcessingServiceStub.AddOrderResponse res = stub
.addOrder(req);
return res.get_return();
} catch (RemoteException e) {
String msg = "Cannot add order"
+ " . Backend service may be unavailable";
throw new Exception(msg, e);
}
}
public String getPrice(String index) throws Exception {
try {
OrderProcessingServiceStub.GetPrice req = new OrderProcessingServiceStub.GetPrice();
req.setIndex(index);
OrderProcessingServiceStub.GetPriceResponse res = stub
.getPrice(req);
return res.get_return();
} catch (RemoteException e) {
String msg = "Cannot get price"
+ " . Backend service may be unavailable";
throw new Exception(msg, e);
}
}
public static void main(String[] args) {
OrderProcessingClient client;
try {
//To test if our client works
client = new OrderProcessingClient();
String res = client.addOrder("013", 5000000);
System.out.println(res);
res = client.getPrice("013");
System.out.println(res);
} catch (AxisFault e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
This is my folder structure of the client

Run the client and see if it works.