I recently had the task of creating a webservice in Java. I was disappointed at how difficult it was and how incomplete and error prone the available documentation is. Creating a webservice in Java is not a trivial exercise. There are a lot of little steps. Miss one and it does not work.
Here are a couple of URLs that I found useful:
http://ws.apache.org/axis/java/user-guide.html
http://axis.apache.org/axis2/java/core/docs/pojoguide.html
I will now try to explain the greater concepts and give adequate details for you to get it to work.
Proper Setup on Tomcat
Webservices do not run as part of the rest of your web application. They run in thier own servlet space. You will be able to use all of the libraries in your base application and I will later explain how to do this.
You need to download AXIS which after being unzipped gives you your own webapps directory with its own WEB-INF directory. Go ahead and take the time to set this up in Maven so that you can easily compile your war file. You have to use the WEB-INF directory that comes with the AXIS download.
In my application, I have a war file for ROOT called ROOT.war, and a war file for webservices called axis.war.
Here is my pom.xml file for convenient compilation using maven including all of the dependencies needed for the webservice.
<code><project xmlns=”http://maven.apache.org/POM/4.0.0” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd“>
<modelVersion>4.0.0</modelVersion>
<groupId>WebServices</groupId>
<artifactId>WebServices</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<name>WebServices</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration> <source>1.6</source> <target>1.6</target> </configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.3</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<dependency>
<groupId>com.opensymphony</groupId>
<artifactId>xwork-core</artifactId>
<version>2.1.6</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>2.7.3</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.9</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>20030203.000550</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.1.8.1</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-struts</artifactId>
<version>2.5.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-struts</artifactId>
<version> 3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.ws.commons.axiom</groupId>
<artifactId>axiom-impl</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
<groupId>org.apache.ws.commons.axiom</groupId>
<artifactId>axiom-api</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
<groupId>org.apache.neethi</groupId>
<artifactId>neethi</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-adb</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-adb-codegen</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-ant-plugin</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-clustering</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-codegen</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-corba</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-fastinfoset</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-jaxbri</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-jaxws</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-jibx</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-json</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-xmlbeans</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-mtompolicy</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.5.0</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
</project>
Go ahead and build your war file using the mvn install command. If you are not familiar with this, then spend time learning Maven from the offical Maven Apache site.
Now, go ahead and deploy it on Tomcat so that you can see that your website works at http://mydomain.com/axis/. You should see a nice splash page that looks like this.
Create the POJO
This apache website at http://axis.apache.org/axis2/java/core/docs/pojoguide.html gives a framework of a webservice with the Weather webservice. I found that certain dependencies did not work so I could not get the example working. Nevertheless, the concepts of the framework are helpful.
Create your service classes such as WeatherService.java, CalculatorService, or any other service or services you need. These classes becomes the basis of your webservices which will eventually be called with URLs such as http://mydomain.com/axis/services/WeatherService/, or http://mydomain.com/axis/services/CalculatorService.
These service classes are to be basic classes. They can be placed in your normal package structure such as in the com.trisummit.webservices package. You can add all sorts of dependencies for all available libraries such as logging, jdbc abstraction layers, libraries in your base application, etc. Your class will need to have a parameterless constructor. Your class will have public and private methods. Public methods will be exposed in the webservice. Private methods will not be exposed in your webservice but are available for your programming pleasure to assist in the logic of your public methods. Your methods can take in whatever parameters you need and return whatever values or classes you want them to return - even container classes of your own creation or just plain Strings. If you want binary content to be part of your return, return a byte array.
Prepare the WEB-INF Directory
In the maven /src/main/webapp/WEB-INF directory, add a directory called services and add the package directory structure of your Service classes.
WEB-INF/services/WeatherService/net/trisummit/webservices/
WEB-INF/services/CalculatorService/net/trisummit/webservices/
You also need to add a META-INF directory with an appropriate services.xml file for each webservice.
WEB-INF/services/WeatherService/META-INF/
WEB-INF/services/CalculatorService/META-INF/
Here is an example of the services.xml file.
<service name=”CalculatorService” scope=”application”>
<description>
Authentication POJO Service
</description>
<messageReceivers>
<messageReceiver mep=”http://www.w3.org/2004/08/wsdl/in-only” />
<messageReceiver mep=”http://www.w3.org/2004/08/wsdl/in-out“ />
</messageReceivers>
<parameter name=”ServiceClass”>
net.trisummit.webservices.CalculatorService
</parameter>
</service>
Now create the deploy.wsdd file in the services directory at
WEB-INF/services/deploy.wsdd
Here is a sample:
<deployment xmlns=”http://xml.apache.org/axis/wsdd/” xmlns:java=”http://xml.apache.org/axis/wsdd/providers/java“>
<service name=”WeatherService” provider=”java:RPC”>
<parameter name=”className” value=”net.trisummit.webservices.WeatherService”/>
<parameter name=”allowedMethods” value=”*”/>
</service>
<service name=”CalculatorService” provider=”java:RPC”>
<parameter name=”className” value=”net.trisummit.webservices.CalculatorService”/>
<parameter name=”allowedMethods” value=”*”/>
</service>
</deployment>
Now you can go ahead and compile the application using the mvn install command.
Restructure and Rebuild
Now you have two more tasks to do before you can send it to the server. And I already know what your are thinking when you read this…You have got to be kidding. You need to place the compiled webservice classes into the target sections of your maven build.
myapplication/target/mywebservices-app-name/WEB-INF/services/net/trisummit/webservices/WeatherService.class
myapplication/target/mywebservices-app-name/WEB-INF/services/net/trisummit/webservices/CalculatorService.class
Next, you need to take the classes of your dependencies, zip them up, change the extension of the zip file to jar, and copy this jar file in the the target lib directory.
myapplication/target/mywebservices-app-name/WEB-INF/classes/ZIP UP EVERYTHING AFTER THIS AND RENAME TO BE A JAR FILE.
Move your new jar file into the lib directory at myapplication/target/mywebservices-app-name/WEB-INF/lib/
Now rebuild your application again using the mvn install command to create your war file and name your war file axis.war.
Now drop your war file on Tomcat and restart your Tomcat App Server.
Start your Webservice
Just putting this on the webserver does not activate the webservice. You have one more very unusual step to take. You have to explicitely start the webservice with a complex command line call which has a significant number of java dependencies.
Create a directory for your webservices dependency jar files – not your webservices, but the dependencies needed for running any and all webservices.
D:\axis\lib
Drop in all of your axis related jar files – in fact, add all jar files related to your project including all dependencies. Then from the command line, execute this command from your services directory, ie D:\Tomcat 7.0\webapps\axis\WEB-INF\services\
java -cp D:\axis\lib\axis2-1.5.5.jar;D:\axis\lib\axis.jar;D:\axis\lib\axis2-saaj-1.5.5.jar;D:\axis\lib\commons-discovery.jar;D:\axis\lib\commons-logging-1.1.jar;D:\axis\lib\jaxrpc.jar;D:\axis\lib\log4j-1.2.14.jar;D:\axis\lib\xerces.jar;D:\axis\lib\xercesImpl.jar;D:\axis\lib\xml-apis.jar;D:\axis\lib\log4j.properties; org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService deploy.wsdd
If you get this message – <Admin>Done processing</Admin> – you did well.
Now test your URLs to see that everything works right. Go to the axis main page and you should see and be able to test everything you need including links to the wsdl of your webservices.

Comments