Jkb's Axis Fun with Google Web Services API
(c) 2005 by Jkb and JkbWorld.com
01/10/2005
JkbWorld.com
Graphics kindly borrowed without permission from Google...

Introduction:

The Google Web Services API is a web service that allows developers like me to learn and integrate Google's famous search engine capabilities into applications. This webpage is an attempt to capture some of the things I learned from it so that someone else might find it useful and also so I won't forget how I did it. Here's my story:


Table of Contents:

  1. Background
  2. Google Web Services API
  3. Apache Axis
  4. TempConversionClient
  5. WSDL2Java
  6. Case Study
  7. Lessons Learned
  8. Next Time
  9. Sources


Background:

Think of "Web Services" as a programming language-independent way to share methods and functions with other programs. These programs may be on the same computer, on the same network, or across the Internet.

I got involved with Web Services while trying to learn about a thing called Internet Parts Ordering (IPO), a standard put together by the AAIA (aftermarket.org). IPO is basically a way to send special orders from an auto parts store to an order processing system using the Internet. IPO uses Web Services to do this, and I didn't know much about Web Services, so that's why I started playing with this stuff to see if I could figure it out and decide if I could build it or buy it for Transpro (transpro.com). Carquest (carquest.com) was the leading IPO partner for a while, so we looked at their IPO files and setup when trying to put ours together.

Ironically, the first place I looked for Web Services examples was Google. I searched for public web services. I figured I could find some publicly available service to talk to, write a consumer, or client, to the service and then see how it worked. I found a few, a Web Service API for Amazon.com, National Oceanic and Atmospheric Administration (NOAA) (noaa.gov) Forecase Service, and finally Google's very own Web Service.

The NOAA Web Service was the first one I looked at, but I managed to confuse the hell out of myself, get frustrated with it and toss it aside. (I may make a similar page for that project in the future) Anyway, I managed to get it to work at a basic level, but could not figure out how to get at the data so I moved on. Amazon's API had a ton of stuff, but I could not think of anything practical to do with it. Finally, I found Google's Web Services API.

Back to Top


Google Web Services API:

Google Web Services API seemed like something useful that I could use. I figured, I can pass it a search term, and it'll pass back some result, right? This made sense to me and did not sound TOO daunting a challenge.

Before I could use Google's stuff, I had to sign up for a developer's account. Basically, this is a free account that will let me do up to 1000 queries per day. In exchange for this free account, Google can get me hooked on queries so that one day I might purchase a license that will let me embed Google into an application and sell it and let Google make money, etc. Click the Google link way down at the bottom to learn more about it.

Once I got my license key, I downloaded the API and started looking at the files. Basically, Google provided several things. First, they provided a Web Services Description Language, or WSDL file (see link below). This file describes in simple, computer language-independent terms, the names of functions, their parameters and return values. They also provided nice Java and C# packages that can allow you to simply and easily connect the Google functionality into your program. Lastly, they provided API documentation and Readme files and lots of other great stuff.

I thought about how to use these new toys that Google had given me, and decided to work with the WSDL file. I figured, since I would not get a nice Java package for IPO (Thanks a lot, Carquest and AAIA), I should work with the WSDL so I wouldn't need to learn it again. Carquest's IPO implementation only provided the WSDL, so I was determined to build a Web Services Client with just the WSDL file. But how?

GoogleSearch.wsdl

Back to Top


Apache Axis:

I searched around for another hour or two looking for a way to get from a WSDL file to a Web Service with no success. I was about to give up, when that very day, I got my issue of Dr. Dobb's Journal (ddj.com) and the featured article was "Building Web Services with Apache Axis". It was a well-written article other than the fact that not a single link from the article worked. It described how simple it was to write a Java web service and deploy it using this nifty Tomcat servlet-based framework called Axis, by the Jakarta project. I knew that I would need to download, install and learn about Axis.

Initially, getting Axis to work was a challenge. I had just installed Java Development Kit 1.5, and it did not occur to me right away that the Stable version of Axis 1.1 would not work with it. After searching around on the Internet and some mailing lists, I discovered that you need Axis 1.2 RC1! Then, I discovered that if you have the Tomcat Security Manager enabled, Axis won't work. You also need to make sure that the Axis directory and files under the Tomcat root are owned by the Tomcat user.

Once Axis is installed, you need to run the happyaxis.jsp page, which then reviews the classpaths and Java libraries in them, suggesting ones that are mandatory for Axis to work, and recommending others to add additional functionality to your implementation. Some of the JAR files are activation.jar, commons-discovery.jar, commons-logging.jar, gnumail.jar, xerces.jar, jaxrpc.jar and others. As you add the many JARs to the classpath, restart Tomcat and view the happyaxis.jsp, your Axis installation becomes more and more happy, until it is reported that all of the dependencies and recommendations are met. At this point, you are ready to use Axis.

The Dr. Dobb's article was pretty good, since it explained exactly what I needed to do in reasonably simple terms and steps. Basically, the article was like "First, you write some methods in a file, name it a .jws file instead of a .java file, and place it in the Axis tree. Oh yeah. That's it, you're done." The simplicity of it was so mind blowing, I thought I must've made a mistake somewhere. But I didn't. I had a nice little web service from the article that converted Fahrenheit to Celcius and back (See TemperatureConversion.jws below). Then, I continued experimenting and wrote one on my own that returned modifications to a String (StringReturn.jws). I thought to myself "Web Services are Easy!". Little did I know that the Web Services gods were watching me... and they were angry.

Dr. Dobb's Article
TemperatureConversion.jws
StringReturn.jws

Back to Top


TempConversionClient:

I did mention the TempConversionClient web service from the article, so I guess it's helpful if I put the client code out here. I used Ant (ant.apache.org) to compile and execute the web service. You'll notice the build.xml file, too, which has the Axis JAR's and dependencies in the Ant classpath. Then, I battled and fought with log4j.properties for a while, too, but I don't remember if I needed it for this example. If not, what the heck, that's what a log4j.properties file looks like.

TempConversionClient.java
build.xml
log4j.properties

Back to Top


WSDL2Java:

Okay... I'm getting off on a tangent with the TemperatureConversion web service and TempConversionClient client. Back to my Google story:

Once I had Axis going and was happy because I figured out Web Services, I started looking into getting from a WSDL file to a Java program. I think my google query was something like "Axis WSDL Java". I got a set of results including a nice little utility called WSDL2Java.

WSDL2Java is an Axis utility that uses the specifications defined in the WSDL file to create the Java Classes needed to use a web service. It sets up the methods of the web service interfaces based on how they are defined in the WSDL.

Here are the files created using the WSDL2Java:

Once created, you simply need to create the client that uses them.

Back to Top


Case Study:

After creating the Java files using WSDL2Java, I was not quite sure where to start. I did some more searching around and discovered a very straightforward example on how to create the Google Web Service consumer on Bawsug. You might notice my GoogleClient.java program looks similar to Bawsug's. That's probably because I was influenced. Ah well.

Once Bawsug pointed me in the right direction, I implemented a Spelling Suggestions check of some test data, which seemed to work reasonably well. I also implemented a search, which produced the search results as expected. It seemed just as simple as the original TemperatureConversion web service!

I decided that the little experiments were fun, but not very interesting. I decided to create a program that would perform a Google search, format, and report back the results for "Jkb" and "Jkb World" in an HTML Page. I guess I'm vain, but then I could use this as a crazy link on my website.

See the Java code for yourself down below. It's not difficult at all to follow. You'll also see the Ant script to compile and execute it, too. I actually cheated and took my original TempConversionClient build.xml file and modified it. I even left the TempConversionClient lines in as "examples". I know... I'm lazy.

When using the WSDL2Java-generated code, there are two important lines that you need to have before you call the web service. These lines are:

GoogleSearchService service = new GoogleSearchServiceLocator();
GoogleSearchPort google = service.getGoogleSearchPort();

Similar to a Factory, you get a new instance of a GoogleSearchService from the Locator, which goes out and finds the GoogleSearchService from the Web Service endpoint's server. Next, you connect the GoogleSearchPort to the service by telling the service to give you an instance. Once completed, you have your link to the web service, and can then call the methods of it. I put a link to a WSDL Tutorial in the Sources section, which describes how WSDL and Web Services work. You will understand what Services and Ports do from reading it.

GoogleClient.java
build.xml
google.html - Search Results

Back to Top


Lessons Learned:

Once I successfully got my GoogleClient web service consumer to work, understood how WSDL2Java worked, and seemed generally comfortable with the way Web Services worked, I talked to a guy over in the Carquest web commerce department, who explained that the SOAP-RPC, or SOAP Remote Procedure Call, technique that I was using was deprecated, and that the industry had moved on to Document Literals and that SOAP-RPC was being removed from the Web Services specifications. Now, I have not searched for whether or not it was being discontinued, particularly since I now had a handle on it and also I suspected that they were blowing smoke, since they have some kind of deal where you can pay them to develop it. But the Web Services Gods had cursed this particular effort by introducing some doubt to the implementation.

The Google Web Services API utilizes SOAP-RPC. SOAP-RPC basically works like a regular function call, the web service function gets passed parameters, and the result is of a known type. Other types of web services use a technique called Document Literal, where the result instead of a known type is a document that can be of any type. Knowing what I do at this point in time, I would say that Document Literal is the main way web services exchange data. Using a web service function like a SOAP-RPC call is a way of utilizing the web services API at a higher level.

Of course, time will tell, and as I experiment more with this technology, the more I will learn and understand about it.

Back to Top


Next Time:

My next Web Services installment will cover Document Literals. I was learning a little about SOAP and Java when I got the book "Java and SOAP" and wrote a simple Web Service client to pull data from the National Weather Service Digital Forecasts. Of course, this took place even before I started playing with Axis. When I discovered how Axis worked, and what a Document Literal was supposed to be, I revisited this program, and figured out how to get at the data stored in the Literal Document, and pull and manipulate the data.

Back to Top


Sources:

The Google Web Services API information can be found at:
http://www.google.com/apis/

The Apache Axis information can be found at:
http://ws.apache.org/axis/

Here is the Bay Area Web Services User Group (BAWSUG) page I followed when I was learning the WSDL2Java:
http://www.bawsug.org/archives/000008.html

This is a W3Schools (w3schools.com) WSDL Tutorial:
http://www.w3schools.com/wsdl/default.asp

Back to Top


Graphics kindly borrowed without permission from Google...