Saturday, May 23, 2009

Consuming webservices in JSP with Apache AXIS

This is a rather old tutorial moved here from my old site on Geocities, hope it's still useful.

Recently I started fumbling around with webservices, a nice integration and communication tool for my customers, what follows is a work in progress, which is going to be enhanced while I proceed in my “trial and error for the illiterate” learning path.
First of all I installed AXIS (http://ws.apache.org/axis/) from the Apache Software foundation and, after validating the installation with the “happyAxis” page, had a working environment for my tests.
The first thing that came to my mind was consuming an external webservice, and I chose to experiment with Tiscali’s public webservices (http://webservices.tiscali.com/).
Axis is able to generate a client for you and I decided to go for it!
It worked automagically, just typed (on my customer’s PC AXIS is located in c:\axis_1-1\):

And in folder ./tiscalisamples (specified with the –o option) some folders and java
files were generated:
./tiscalisample/com/tiscali/webservices/some java files :
  1. ArrayOfServiceTest.java
  2. deploy.wsdd
  3. ServiceTest.java
  4. SmtpResult.java
  5. Tiscali_x0020_Email_x0020_Services.java
  6. Tiscali_x0020_Email_x0020_ServicesLocator.java
  7. Tiscali_x0020_Email_x0020_ServicesSoap.java
  8. Tiscali_x0020_Email_x0020_ServicesSoapImpl.java
  9. Tiscali_x0020_Email_x0020_ServicesSoapStub.java
  10. undeploy.wsdd
Now I compiled the whole lot :

C:\axis-1_1\dist>javac -classpath C:\axis-1_1\lib\axis.jar;C:\C:\axis-1_1\lib\jaxrpc.jar;C:\axis-1_1\lib\commons-logging.jar;
C:\axis-1_1\lib\commons-discovery.jar;C:\axis-1_1\lib\saaj.jar;C:\axis-1_1\lib\xercesImpl.jar;C:\axis-1_1\lib\xml-apis.jar
C:/axis-1_1/dist/tiscalisample/com/tiscali/webservices/*.java


And so it all ended up in a bunch of .class files in the same folder.

Then I copied the whole ./com/tiscali/webservices/*.class to the ./WEBINF/classes folder of the standard “examples” webapp shipped with Tomcat.
Now the “real” client, those were only helper classes, I chose to write it in jsp for simplicity, it all boiled down to a few lines:

<%@ page contentType="text/html; charset=iso-8859-1" language="java" errorPage="" %>





<% com.tiscali.webservices.Tiscali_x0020_Email_x0020_ServicesLocator aLocator = new com.tiscali.webservices.Tiscali_x0020_Email_x0020_ServicesLocator();
com.tiscali.webservices.Tiscali_x0020_Email_x0020_ServicesSoap aServicesSoap = aLocator.getTiscali_x0020_Email_x0020_ServicesSoap();
String validatorResult = aServicesSoap.isValidEmail("mail@xyz.com");
out.write(validatorResult); %>



Which returned “true” as this is a valid (even if probably not existent) email address.

This made me happy and prompted for further investigation of those “webservices”.

The nice thing of this code is that WSDL2Java (the tool I called from the command line) has done almost all the work for me, I just had to compile the code and call it’s methods, then I did some reading on Axis’s site and decided to experiment with direct usage of Axis.

First I set up a simple SOAP service, using Axis’s ability to build a service from a java file, a very simple one:
Here is the code (helloEverybody.jws):

  1. public class helloEverybody {
  2. public String hello()
  3. {
  4. String results = "Hello everybody";
  5. return results;
  6. }
  7. }

I placed the file in c:\axis-1_1\webapps\axis and started looking at it’s WSDL description with the url http://localhost:8080/axis/helloEverybody.jws?wsdl
Looking at it you can quickly get some infos:

The service section:








Shows you the service address (to be called by your client) and the soap port, named “helloEverybody”.










And for details on the response:




The rest of the WSDL shows clearly that there is only one method to be called “hello” which returns a response of type “string” (Axis’s site details mapping between xsd types and java types).
This is the jsp client I put up:


<%@ page contentType="text/html; charset=iso-8859-1" language="java" import="org.apache.axis.client.Service, org.apache.axis.encoding.XMLType, javax.xml.rpc.*;" errorPage="" %>





<% String host = "http://localhost:8080"; String servicepath = "/axis/helloEverybody.jws";
String endpoint = host + servicepath;
String method = "hello" ;
String ret = null;
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(endpoint);
call.setOperationName(new javax.xml.namespace.QName (method));
ret = (String)
call.invoke(( Object [] )null);
out.write("Got result : " + ret);
%>


The “endpoint” and “method” corresponds to what I wrote above.
According to Axis guides I created a service and a call from that service, then I set an endpoint and an operation name for that call. After this I invoked the call (without input parameters and displayed the response converting it to a string for compatibility.

Next steps will be securing the service with a Realm and https and consuming it from jsp with direct usage of Axis.

1 comment:

Unknown said...

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>

<%@ page

import="org.apache.axis.client.Call,org.apache.axis.client.Service,org.apache.axis.encoding.XMLType,
org.apache.axis.utils.Options,javax.xml.rpc.ParameterMode,java.net.URL"
%>
<% String host = "http://localhost:8080"; String servicepath = "/http://localhost:8080/Web1/services/HelloEverybody?wsdl";
String endpoint = host + servicepath;
String method = "hello" ;
String ret = null;
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(endpoint);
call.setOperationName(new javax.xml.namespace.QName (method));
ret = (String)
call.invoke(( Object [] )null);
out.write("Got result : " + ret);
%>

org.apache.jasper.JasperException: Unable to compile class for JSP:

An error occurred at line: 6 in the generated java file
Only a type can be imported. org.apache.axis.client.Call resolves to a package


please give me the solution