Friday, May 23, 2014


Hi, in this series of Posts I will be explaining you how to create a AXIOM based AXIS2 web service.

The full article will contain three parts, the first part will explain how to create the Server component of the Service and how to deploy it, the second part will explain how to test the service using SOAPUI, the final part will explain how to create the client component of the service.


Ok so Lets Get started 


What is Apache Axis2


Axis2 is a engine for web-services, Axis2 allows developers to develop both the client and the server side of a webservice and to host web services. Main communication method Axis2 uses is SOAP messaging and it allows you to do the following,
  • Send SOAP messages 
  • Receive and process SOAP messages 
  • Create a Web service out of a plain Java class 
  • Create implementation classes for both the server and client using WSDL 
  • Easily retrieve the WSDL for a service 
  • Send and receive SOAP messages with attachments 
  • Create or utilize a REST-based Web service 
  • Create or utilize services that take advantage of the WS-Security, WS-ReliableMessaging, WS-Addressing,WS-Coordination, and WS-Atomic Transaction recommendations 
  • Can use Axis2's modular structure to easily add support for new recommendations as they emerge etc.
This artical will not cover Axis2 in detail, to understand Axis2 features and its architecture please refer to Axis2 user manuals.


What is AXIOM


Axiom stands for Axis Object Model. The Apache Axiom library provides an XML Infoset compliant object model implementation which supports on-demand building of the object tree.  AXIOM is the object model for Apache Axis 2,  AXIOM is different from existing XML object models in various ways, the major one being the way it incrementally builds the memory model of an incoming XML source. AXIOM itself does not contain a parser and it depends on StAX (Streaming API for XML) for input and output.

If you want to learn more about AXIOM follow this

Developing Axis2 Web Service



The development will be done without using any additional integration plugins for IDE. For coding I will be using eclipse IDE, you can use any other IDE you like.

Architecture of the service

The sample implementation is a Order Processing service where the service will contain two methods, "Set Product" and "Get Product" methods. The "Set Product" will allow the client to set product details and "Get Product" will allow the client to retrieve information about a specific product.  All the other functionality like handling Customer Orders, Calculating Cost, Customer Item list management will be handled in the client side.


Prerequisites 

  • Downlad, install and configure Apache Axis2, and the installation location of Axis2 will be referred as <AXIS2_HOME> for later references.
  • Setup Java Development environment. 

Developing the Service


Step 1 : Writing the service Class
  1. Create a new Java Project and lets name it "Axis2_Webservice".
  2. Within "src" directory let's create a package as follows, "televisionshop.service"
  3. Within the created package create a new java class named "Television.java", this will be used to store information of each television by creating objects for each television.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package televisionshop.service;

public class television {
 String model = "Dummy";
 String price = "Dummy";
 String availableQuantity = "Dummy";

 public String getModel() {
  return model;
 }

 public void setModel(String model) {
  this.model = model;
 }

 /**
  * @return the price
  */
 public String getPrice() {
  return price;
 }

 /**
  * @param price
  *            the price to set
  */
 public void setPrice(String price) {
  this.price = price;
 }

 /**
  * @return the availableQuantity
  */
 public String getAvailableQuantity() {
  return availableQuantity;
 }

 /**
  * @param availableQuantity
  *            the availableQuantity to set
  */
 public void setAvailableQuantity(String availableQuantity) {
  this.availableQuantity = availableQuantity;
 }

}

  1. Now add the dependencies that are required for the service class as external jars. The requires Jars can be locates at <AXIS2_HOME>/libs directory. Add the following jars to your class path.
  • axiom-api-x.x.xx 
  • axiom-dom.x.x.xx 
  • axiom-impl.x.x.xx 
  1. Create another Class named "TelevisionShopService.java" within the same package with the following code snippets.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package televisionshop.service;


import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import javax.xml.stream.XMLStreamException;
import javax.xml.namespace.QName;
import java.util.HashMap;

public class TelevisionShopService {

 private HashMap<String, television> map = new HashMap<String, television>();

 private String namespace = "http://myshop.com/xsd";


 public OMElement getProduct(OMElement element) throws XMLStreamException {

  // build the xml tree using AXIOM
  element.build();
  // detach the node from its parent container
  element.detach();

  // Get First element which is product id
  OMElement idElement = element.getFirstElement();
  String id = idElement.getText();

  // Get the product details from hash map
  String model = map.get(id).getModel();
  String price = map.get(id).getPrice();
  String qty = map.get(id).getAvailableQuantity();

  // Build the response
  OMFactory fac = OMAbstractFactory.getOMFactory();

  // Create name space definition
  OMNamespace omNs = fac.createOMNamespace(namespace, "ns");
  // Create response element
  OMElement method = fac.createOMElement("getProductResponse", omNs);

  // Create element called return
  OMElement value = fac.createOMElement("model", omNs);
  OMElement value1 = fac.createOMElement("price", omNs);
  OMElement value2 = fac.createOMElement("qty", omNs);

  // add elements according to hierarchy
  value.addChild(fac.createOMText(value, model));
  method.addChild(value);
  value1.addChild(fac.createOMText(value1, price));
  method.addChild(value1);
  value2.addChild(fac.createOMText(value2, qty));
  method.addChild(value2);

  return method;
  // return element;

 }

 public void setProduct(OMElement element) throws XMLStreamException {
  television tele = new television();

  element.build();
  element.detach();

  // Get product id from request XML
  OMElement prodIdElement = element.getFirstChildWithName(new QName(
    namespace, "id"));
  String id = prodIdElement.getText();

  OMElement proDetailElement = element.getFirstChildWithName(new QName(
    namespace, "model"));
  String model = proDetailElement.getText();
  tele.setModel(model);

  OMElement proPriceElement = element.getFirstChildWithName(new QName(
    namespace, "price"));
  String price = proPriceElement.getText();
  tele.setPrice(price);

  OMElement qtyElement = element.getFirstChildWithName(new QName(
    namespace, "qty"));
  String qty = qtyElement.getText();
  tele.setAvailableQuantity(qty);
  
  System.out.println("[Product Set] : ID" +id+ " : Name : " +model+ " : Price : "+price+ " : Qualtity : " +qty);

  map.put(id, tele);
 }
}

Note : As you can see above four parameters are parsed to the service class to set product details, namely; id, model, price and quantity.

Step 2 : Writing The Service Descriptor 
  1. Now create the service descriptor file (service.xml) so Axis2 will be able to identify the corresponding classes and methods of the service, to create the service.xml file create a directory named "META-INF" at the root level of your project and place the service.xml file in that folder with the following content.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<service name="TelevisionShopService" scope="application">
 <description>
  TelevisionShopService
 </description>
 <operation name="getProduct">
  <messageReceiver
   class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver" />
 </operation>
 <operation name="setProduct">
  <messageReceiver
   class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver" />
 </operation>
 <parameter name="ServiceClass">televisionshop.service.TelevisionShopService
 </parameter>
</service>
Note : Axis2 has a set of built-in message receivers; some of them can only handle a XML-in, XML-out scenarios and those are called RawXML message receivers. Meanwhile, there are message receivers that can handle any kind of JavaBeans + simple Java types + XML; those are called RPC message receivers. As you can see from the above service Descriptor parameter named "ServiceClass"  specifies the main service class.

After creating all the files the Folder structure of the project will look like this, 



Step 3 : Creating a service Archive file to deploy the service
  1. The service archive type that is supported by Axis2 is .arr (Axis ARchive), the file structure of a .aar file is similar to a .jar file. So in order to create the service archive (.arr file) just export the project to a Jar file and change the extension of the file from .jar to .aar. (FileName.jar to FileName.aar)
  • The file can be exported as a jar file in eclipse by going to the file menu and selecting export command and selecting export type as JAR. 
  • The file can be exported to a jar file in Intellij by following this.
  1. Next place the created .aar file in <AXIS2_HOME>/repository/services directory. Now start the Axis2 server by running the "axis2server.sh" file located in <AXIS2_HOME>/bin directory. Axis2 will automatically deploy the service.
  2. Now go to the URL where AXIS server is running at, in my case the location is "http://localhost:8080/axis2/services/". If you go to this URL you will be able to view the service you created if it is successfully deployed, click on the service to view the WSDL of the service. 


Now you have successfully created the service component and deployed it, In the next post I'll explain how to test the service without a client.

Thank You for reading and Your feedback is highly appreciated. :)



Categories: , , ,

2 comments:

  1. Nice writing. Found your website perfect for my needs. thanx a lot & keep on doing... :)

    ReplyDelete

Subscribe to RSS Feed Follow me on Twitter!