Tomcat/Axis WebServices - Client
Please note that due to the current funding situation, the NGS no longer supports a Web Service interface to its resources, but we have kept this tutorial online in case it is of use for users of other Grids.
Web service using Tomcat/Axis (Part I - Client)
1. Introduction
This is a practical of exercises on Web services using Tomcat/Axis.
While Web services can refer to any Web-based interfaces, the mainstream is still the W3C defined heavyweight standard where data and operations are described by WSDL, and messaging is by SOAP. Tomcat/Axis is an implementation of this kind of Web service framework.
In this exercise, We're going to see how to use a published Web service programmatically. The Web service is provided by NCBI (National Center for Biotechnology Information) for their biomedical and genomic databases.
2. Preparation of required software
We may need to download and install some software packages to support our development. Some of them require environment variables to be set.
- Tomcat 6
- http://tomcat.apache.org/download-60.cgi
- export CATALINA_HOME=<tomcat home directory>
- Axis 1.4
- http://ws.apache.org/axis/java/releases.html
- Unzip it and copy subdirectory axis under webapps to Tomcat's webapps directory
- export AXIS_HOME=<Axis home directory>
- Ant
- http://ant.apache.org/bindownload.cgi
- export ANT_HOME=<ant directory>
- export PATH=$PATH:$ANT_HOME/bin
- Additional jar files
- We need activation and mail jar libraries
- activation.jar
- mail.jar
- Put them in Tomcat's lib directory
3. Create our project
Now we're ready to get started. First, let's create a project directory, and a build file for Ant.
- mkdir pubmed
- cd pubmed
Here is the initial content of build.xml file, copy and save it as
build.xml
and we'll add targets to it later:
<?xml version="1.0"?>
<project name="A Webservice App" basedir=".">
<property environment="env"/>
<path id="classpath">
<fileset dir="${env.CATALINA_HOME}/lib">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${env.AXIS_HOME}/lib">
<include name="**/*.jar"/>
</fileset>
</path>
</project>
4. Build a stub for Web service client
A Web service is defined in a WSDL document and published as a Web resource. We can use Axis toolkit to generate the interface programs in Java from the WSDL document. The generated interface programs are called the stubs to the service running on the server. Our client application program will call these stubs like local code and Axis tools will handle the communication between the client and server.
The NCBI Web service is published as Entrez utilities, and the WSDL document is at http://eutils.ncbi.nlm.nih.gov/entrez/eutils/soap/eutils.wsdl. We can read the document online, and we can generate the stub using the Axis WSDL2Java tool without downloading it.
Add a target to the build file to compile webservice client stub from the WSDL document
<target name="entrez-stub">
<mkdir dir="entrez"/>
<java classname="org.apache.axis.wsdl.WSDL2Java" fork="true" dir="entrez">
<classpath refid="classpath" />
<arg value="http://eutils.ncbi.nlm.nih.gov/entrez/eutils/soap/eutils.wsdl"/>
</java>
</target>
Run the target:
It takes a while to generate Java source code for the WSDL. Basically, it will generate a common locator for the Web service port type, a Java class for the port type and methods for the operations. The data types defined in the WSDL as complex types of XML Schema will be translated to Java classes with child elements as properties and accessors (getters and setters).
You can check the subdirectory in build to see all the Java source code.
Then, let's compile the generated source code. We use the following Ant target:
<target name="entrez-compile" description="Generate ncbi.jar file from eutils.wsdl">
<mkdir dir="entrez/build" />
<javac destdir="entrez/build" fork="yes" memoryMaximumSize="512m">
<src path="entrez" />
<classpath refid="classpath" />
</javac>
</target>
Make a jar file of all compiled .class files:
<target name="entrez-jar">
<jar destfile="ncbi.jar" basedir="entrez/build" />
</target>
5. Find out the interface from WSDL
Let's have a brief analysis of the WSDL document. From <service name="eUtilsService"><port name="eUtilsServiceSoap", we know there is an EUtilsServiceLocator, and from this locator, we can get the port/class EUtilsServiceSoap.
From PortType definitions <portType name="eUtilsServiceSoap"> we can find out all operations/methods of the port/class EUtilsServiceSoap. Here we're going to check the operation "eSearch". The eSearch function is used to search the databases for articles or journals by keywords.
<operation name="run_eSearch"> <input message="s0:eSearchRequest_m"/> <output message="s0:eSearchResponse_m"/> </operation>
From this fragment, we know a public method run_eSearch accepts a eSearchRequest_m as input and returns a eSearchResponse_m as output.
From Message definition:
<message name="eSearchRequest_m"> <part name="parameters" element="nsese:eSearchRequest" /> </message> <message name="eSearchResponse_m"> <part name="parameters" element="nsese:eSearchResult" /> </message>
We know the input and output parameters are XML elements defined in another namespace 'nsese' and the external document is 'esearch.xsd'.
By browsing to http://eutils.ncbi.nlm.nih.gov/entrez/eutils/soap/esearch.xsd, we find out:
<s:element name="eSearchRequest">
<s:complexType>
<s:sequence>
<s:element name="db" type="s:string" minOccurs="0"/>
<s:element name="term" type="s:string" minOccurs="0"/>
<s:element name="WebEnv" type="s:string" minOccurs="0"/>
<s:element name="QueryKey" type="s:string" minOccurs="0"/>
... ...
These elements will be the accessors of the ESearchRequest class. You can find out from the stub: gov/nih/nlm/ncbi/www/soap/eutils/esearch/ESearchRequest.java
6. Write a client query program
Once we have a clear picture of the Web service interface, we can write client applications to call the service operations. The following code calls eSearch operation to query article IDs for key phrase "sleep disorders".
import gov.nih.nlm.ncbi.www.soap.eutils.*;
import gov.nih.nlm.ncbi.www.soap.eutils.esearch.*;
public class PubmedQuery
{
public static void main(String[] args) throws Exception
{
EUtilsServiceLocator service = new EUtilsServiceLocator();
EUtilsServiceSoap utils = service.geteUtilsServiceSoap();
ESearchRequest parameters = new ESearchRequest();
parameters.setDb("pubmed");
parameters.setTerm("sleep disorders");
ESearchResult result = utils.run_eSearch(parameters);
for (String s : result.getIdList())
System.out.println(s);
}
}
Save the code as PubmedQuery.java and then compile and run it. To compile this program, we need to set classpath to ncbi.jar stub we generated above as well as the Axis jar files. It is easier to add a Ant target to our build file:
<target name="compile-me">
<javac srcdir="." sourcepath="" destdir="." fork="yes">
<include name="*.java"/>
<classpath>
<pathelement location="."/>
<pathelement path="ncbi.jar"/>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<target name="run-me">
<property name="classname" value="PubmedQuery"/>
<java classname="${classname}" fork="yes">
<classpath>
<pathelement location="."/>
<pathelement path="ncbi.jar"/>
<path refid="classpath"/>
</classpath>
</java>
</target>
Now run the targets:
The result is like this:
Buildfile: build.xml
run-me:
[java] 20066610
[java] 20064746
[java] 20063014
[java] 20061419
[java] 20058760
[java] 20055251
[java] 19962495
[java] 19962492
[java] 20054743
[java] 20054208
[java] 20053313
[java] 20052864
[java] 20052524
[java] 20051895
[java] 20051221
[java] 20051158
[java] 20050997
[java] 20050885
[java] 20049219
[java] 20049146
BUILD SUCCESSFUL
Total time: 6 seconds
So far so good, and writing a web service client can be as simple as that. Let's do some more exercises on PubMed.
7. More exercises
(1) Get database info using eInfo
You can get a list of databases from eInfo request, find out the parameters from either WSDL or Java stub. If no database name is given, a list of all databases should be displayed, or fields of the specified database are displayed.
(2) eSummary
Call eSummary with pubmed database and IDs 11850928,11482001.
(3) Get articles by IDs using eFetch
This is the most difficult exercise. You can do it if you still have time and patience. At the time of testing this tutorial, the Entrez SOAP API has a bug on eFetch, it may or may not have been fixed and you can work it out yourself. Check the document about it: http://www.ncbi.nlm.nih.gov/entrez/query/static/esoap_help.html.
In addition to the eutils.wsdl, you also need to generate Java stub for http://www.ncbi.nlm.nih.gov/entrez/eutils/soap/v2.0/efetch_pubmed.wsdl and then reference the jar files specifically for efetch_pubmed or any other specified database.
- Login to post comments

