In this post, i mention about the creation of a dynamic web service. Nevertheless, there was mentioned that “One approach would be to use WSDL2Java, the code generation tool provided with Axis2 generate a stub for the web service and use that stub to consume the web service.” So here is this approach. This post could be actually named:
Use Apache Axis tools to generate Web services clients and configure advanced options
Autogenerate your client source code
From the time that you've got a new-and-improved Web service, and you've limited the right methods (or, rather, allowed the right methods), thanks to Axis, you can publish a WSDL file representing the service. Or alternatively, you might just have the necessary url, a position from where you can contact the proper WSDL. From this point, you (or world) can use the Web service. The only problem is that the world (and you :) ) hasn't figured out how to write JAX-RPC style Web service clients.
This isn't an uncommon problem, especially with Web services and related technologies changing at a blistering pace. Fortunately, there's an answer: code autogeneration. Given just a WSDL file, you or another developer can painlessly generate a set of Java client classes that can connect to that service.
Code generation has traditionally been a pretty disappointing exercise, and code-generation tools usually are more pain than help. Thankfully, that's largely not the case with JAX-RPC, and specifically Axis. Axis produces WSDL for your services and can consume that same WSDL to generate usable Java classes.
Get a WSDL file for your service
The first step in code generation is to get a WSDL file for your service. This is easy: just navigate to the URL that your service is deployed at. Suppose that in the case of
SomethingSearcher, that's http://localhost:8080/axis/services/SomethingSearcherService. Then, simply tack ?wsdl onto the end of your URL, like this: http://localhost:8080/axis/services/SomethingSearcherService?wsdl. You may get a blank screen from your browser, or a request to download a file, or some sort of pretty-printed XML.
Whatever your browser does, it's trying to deal with what Axis provides: a WSDL file for that service. In Safari, you can view source to see the XML; Firefox is similar, although Firefox tries to display the XML . It's critical that you just get a copy of that WSDL document.
Open up the XML; you should see something that looks like Listing 1 (although the listing only shows part of the WSDL; it might be a very long file):
In these types of actions (meaning the java and particularly web services), it is in common usage the notion of Stub:
Stubs represent remote classes and allow you to work with those remote classes as if they were local.
The scope is to be able to write a client in order to use your stubs.
With a WSDL file in hand, you're ready to use another command-line tool from Axis:
WSDL2Java. You can run it and see all the options, as displayed in Listing 2:
All the options in Listing 2 are a bit confusing, so you can boil it down further: simply run
WSDL2Java and supply it the name of the WSDL file you want it to generate code from. So save the WSDL output you got from the
SomethingSearcher.wsdl (or try to feed it directly from the url: http://localhost:8080/axis/services/SomethingSearcherService?wsdl)
WSDL2Java and supply the command the WSDL you just saved, as shown bellow:
[your command prompt]>java org.apache.axis.wsdl.WSDL2Java SomethingSearcherService.wsdl (or if your connection and environment permits: http://localhost:8080/axis/services/SomethingSearcherService?wsdl]
You won't get any visible response at all. But the command creates a new directory, with several nested subdirectories, in your file system. If you're running your service on your local machine, the directory is called localhost.
The topmost folder matches the service's host name (in this case, localhost). Then, you have the path to the service. Because the URL is http://localhost/axis/services/SomethingSearcherService, the file folder structure is localhost/axis/services/SomethingSearcherService. Underneath that last folder are four files:
- SomethingSearcher.java: An interface defining the methods available on the Web service.
- SomethingSearcherService.java: An interface defining methods for locating an appropriate Web service.
- SomethingSearcherServiceLocator.java: An implementation of SomethingSearcherService; it handles service location.
- SomethingSearcherServiceSoapBindingStub.java: An implementation of SomethingSearcher. This is the class that you'll use to interact with the Web service in your client code.
So, for example, Listing 3 shows the source of
You might have noticed that the generated classes share a lot of names with your existing Java classes. The packaging of the generated code should prevent real problems, but be careful when you compile that you don't overwrite other class files with the same name.
This is the only one of the four classes that is easily decipherable. The others are substantially more complex and full of JAX-RPC syntax and semantics. That's the whole idea, though: let JAX-RPC and Axis deal with all the Web service details, and allow a developer to just write basic code.
All that's left is to actually use the generated stubs. That's a matter of compiling them, making sure they're in your classpath, and then knowing which methods to call (and how to call those methods).
Compile all your generated classes
Navigate back to your root directory. That's the directory where you've been keeping all your Java source files and running programs from. You probably have your generated classes off of that directory; if you've been running your service on your local machine, the localhost autogenerated directory should be just under your root. Then, compile all of the generated source code, as shown in Listing 4:
[your command prompt]
javac -d . localhost/axis/services/SomethingSearcherService/*.java
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
If you've already got your classpath set up for Axis and JAX-RPC, you shouldn't need to make any additions or changes to get these classes to compile. If you're running Java SE 5 or later, you'll probably get warnings similar to those shown in Listing 4; that's because the code doesn't use parameterized types. Don't worry about those warnings; they won't affect your Web service work.
Next, you need to build a client. Here are the basic steps you'll follow any time you use generated classes from Axis:
- Instantiate an implementation of your service class, using the generated locator class.
- Get an instance of the class that represents your service.
- Invoke methods on that class as if the service were local.
That's all a bit abstract; look at Listing 5, which puts these steps into action:
Here's how the code maps to the three steps I listed above:
Instantiate an implementation of your service class, using the generated locator class: You need a connection to the Web service. The auto-generated classes take care of all the semantics, so all you need is a single line:
SomethingSearcherService service = new SomethingSearcherServiceLocator();
This creates a new class that knows how to locate your Web service.
Get an instance of the class that represents your service: This class is called a stub. Stubs represent remote classes and allow you to work with those remote classes as if they were local. Here's how to get a stub for your Web service:
localhost.axis.services.SomethingSearcherService.SomethingSearcher searcher =
SomethingSearcherwith its complete package name to avoid any confusion about which
SomethingSearcheris being used. Recall that the actual Java class used to create the Web service was called
SomethingSearcher, and you may even have that source and class file in your current directory. By using a full package name, you eliminate the risk of name collisions.
Invoke methods on that (stub) class as if the service were local: The wonderful thing about a stub class is that it protects your code from network and Web service syntax. You just call methods on the stub as if it were the Web service:
Object results = searcher.search(keyword);
The think here is that you must have in mind, is there's no JAX-RPC code that the client needs to deal with. All that code is abstracted away in the autogenerated source code.
All that's left to do is run your client. Compile it and then run the class, as shown in Listing 6:
[your command prompt]>> java WSDLClient marketing
Returned something for keyword 'searchterm':
That's a huge improvement, and you can teach anyone these three steps. The result? Your Web service is now available to people who know JAX-RPC ... and to those who don't. That's priceless.