This article will explain how to use complex types in a web service with Apache Axis.
Part-I will cover a simple web service that uses complex types.
Part-II will cover a slightly advanced web service that uses an array of complex types.
A little fundamentals:
The below questions are just to recap your knowledge and will not address a detailed introduction.
What are web services ?
In simple terms a web service is an application or business logic that is
accessible using standard Internet protocols
What is Apache Axis ?
The Apache Axis is a webservice implementation tool based on open source and the Apache standards.
This article will use Apache Axis web services engine for its demonstration.
Visit http://ws.apache.org/axis/java for more information about the Apache Axis.
What are primitive types and complex types?
In Java, primitive types includes data types like int, char,short, float, byte, boolean, long and byte array." Similarly complex types are objects
created by the developer. For example an object called Tree with the properties 'Stem, Leaves' is a complex type.
Object: Tree |
Attributes: Stem Leaves |
Getting ready with the system:
What you need to run this demo ?
Apache Axis and the resource files can be plugged-in with most of the servlet containers.
Setting up the Apache Axis with a Servlet container is beyond the scope of this article which is explained very
well in here.
The reader is highly recommended to read the installation instructions of Apache Axis and try to
deploy and run a simple web service before running this demonstration.
Note: For this demonstration, the resource files will be hosted in Axis + Servlet container
and the client will be a JSP page.
Object: Company |
Attributes: ID Names EmployeeNames[ ] |
<?xml version="1.0" encoding="UTF-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <getCompanyDataResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <getCompanyDataReturn href="#id0" /> </getCompanyDataResponse> <multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns1:Company" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:CompanyService"> <companyID href="#id1" /> <companyName xsi:type="soapenc:string">Test</companyName> <employeeNames xsi:type="soapenc:string">Balaji</employeeNames> <employeeNames xsi:type="soapenc:string">LSMS</employeeNames> <employeeNames xsi:type="soapenc:string">LQ</employeeNames> </multiRef> <multiRef id="id1" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">2311</multiRef> </soapenv:Body> </soapenv:Envelope> |
package com.server; public class Company { public int companyID; public String companyName; public String[ ] employeeNames; } |
package com.server; public class CompanyService{ /** * @return company object */ public Company getCompanyData(){ Company company = new Company(); String [] employeeNames = new String[] { "Balaji", "LSMS" , "LLQ" }; company.companyID = 2311; company.companyName = "Test"; company.employeeNames = employeeNames; return company; } } |
java org.apache.axis.client.AdminClient deployCompanyService.wsddAfter executing the above command, the command window should display "Done processing".
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="CompanyRepository" provider="java:RPC"> <parameter name="className" value="com.server.CompanyService"/> <parameter name="allowedMethods" value="getCompanyData"/> <parameter name="wsdlTargetNamespace" value="CompanyService"/> <beanMapping qname="myNS:Company" xmlns:myNS="urn:CompanyService" languageSpecificType="com.server.Company"/> </service> </deployment> |
java org.apache.axis.wsdl.WSDL2Java -p com.client http://<servername:port>/<webcontext name>/services/CompanyRepository?wsdlThe option -p com.client in the above command will tell the WSDL2Java to create all the stub files with the package name and directory com.client respectively.
<!-- The package import com.client.* will import all the necessary class files to be used later --> |
|
|
<?xml version="1.0" encoding="UTF-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <getIndustryDataResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <getIndustryDataReturn href="#id0" /> </getIndustryDataResponse> <multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns1:Industry" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:IndustryService"> <industryID href="#id1" /> <industryName xsi:type="soapenc:string">Test</industryName> <products href="#id2" /> <products href="#id3" /> </multiRef> <multiRef id="id3" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:Product" xmlns:ns2="urn:IndustryService" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"> <productID href="#id4" /> <productName xsi:type="soapenc:string">Light Beamer</productName> </multiRef> <multiRef id="id1" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">2311</multiRef> <multiRef id="id2" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns3:Product" xmlns:ns3="urn:IndustryService" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"> <productID href="#id5" /> <productName xsi:type="soapenc:string">Sensor Light</productName> </multiRef> <multiRef id="id5" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">712</multiRef> <multiRef id="id4" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">1774</multiRef> </soapenv:Body> </soapenv:Envelope> |
package com.server; public class Industry { public int industryID; public String industryName; public Product[ ] products; } |
package com.server; public class IndustryService{ /** * @param industryID * @return industry object */ public Industry getIndustryData(int industryID){ Product product1 = new Product(); product1.productID = 712; product1.productName = "Sensor Light"; Product product2 = new Product(); product2.productID = 1774; product2.productName = "Light Beamer"; Product [] products = new Product[] { product1, product2 }; Industry industry = new Industry(); industry.industryID = 2311; industry.industryName = "Test"; industry.products = products; return industry; } } |
package com.server; public class IndustryService { //will copy the complete source code soon..wait public Industry getIndustryData(int industryID){ .. .. .. return industry; } } |
java org.apache.axis.client.AdminClient deployIndustryService.wsddThe command window should display "Done processing" after executing the above command.
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="IndustryRepository" provider="java:RPC" style="rpc" use="encoded"> <parameter name="wsdlTargetNamespace" value="urn:IndustryService"/> <parameter name="className" value="com.server.IndustryService"/> <parameter name="allowedMethods" value="getIndustryData"/> <typeMapping xmlns:ns="urn:IndustryService" qname="ns:Industry" type="java:com.server.Industry" serializer="org.apache.axis.encoding.ser.BeanSerializerFactory" deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> <typeMapping xmlns:ns="urn:IndustryService" qname="ns:Product" type="java:com.server.Product" serializer="org.apache.axis.encoding.ser.BeanSerializerFactory" deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> <typeMapping xmlns:ns="urn:IndustryService" qname="ns:ProductArray" type="java:com.server.Product[]" serializer="org.apache.axis.encoding.ser.ArraySerializerFactory" deserializer="org.apache.axis.encoding.ser.ArrayDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> </service> </deployment> |
java org.apache.axis.wsdl.WSDL2Java -p com.client http://<servername:port>/<webcontext name>/services/IndustryRepository?wsdlCompile the Java based client stubs.
<!-- The package import com.client.* will import all the necessary class files to be used later --> <%@ page import ="com.client.*, javax.xml.rpc.Service, java.net.URL" %> <% //Initialize the endpoint java.net.URL endpoint = new java.net.URL("http://<servername:port>/<web context name>/services/IndustryRepository"); //Replace the servername and context according to your server settings IndustryRepositorySoapBindingStub stub = new IndustryRepositorySoapBindingStub(endpoint,null); //Initialize the stub class with the endpoint variable. %> <html> <head> <title>Access Industry Service</title> </head> <body text="#0077FF"> <p style="margin-top='30px'"> <h3>Industry Repository Access WebService ::: JSP Client</h3> <% try{ //Call the method and assign the returned result to the company object // A more elegant coding practice shd be used for proper error handling, //this is only a demo, axis fault or soap fault is not handled. Industry industry = stub.getIndustryData(2311); //Display datas out.println("<b>Industry name: </b>" + industry.getIndustryName()); out.println("<br><b>Industry ID: </b>" + industry.getIndustryID()); out.println("<br><b>Product Details:: </b>"); Product[] products = industry.getProducts(); for(int i=0; i< products.length; i++) out.println("<br> -" + products[i].getProductID() + ":" + products[i].getProductName()); }catch(Exception e) {out.println("Error in get and display data: <br>" + e); } %> </p> </body> </html> |
Private Sub GetData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GetData.Click Dim IndustryService As New net.client.IndustryServiceService Dim industry As New net.client.Industry Dim product As New net.client.Product industry = IndustryService.getIndustryData(2311) ResultBox.Text = "Industry name:" & industry.IndustryName ResultBox.Text = ResultBox.Text & ControlChars.NewLine ResultBox.Text = ResultBox.Text & "Industry ID:" & industry.IndustryID ResultBox.Text = ResultBox.Text & ControlChars.NewLine & "Products Details::" ResultBox.Text = ResultBox.Text & ControlChars.NewLine product = industry.products Dim i As Integer For i = 0 To product.Length ResultBox.Text = ResultBox.Text & " -"& product(i).productID & ":" & product(i).productName & ControlChars.NewLine Next End Sub |