10.17. Implementing a Web Service ClientTo implement a Web Service Client, we need to do the following:
After downloading the WSDL and saving it to client/InventoryService.wsdl under the ch10 project root directory, we use the Axis 1.1 WSDL2Java Ant task in the client build.xml file to generate our Web Service proxy objects and custom data types (Example 10-14). Example 10-14. client/build.xml... <property name="axis.lib.dir" value="/Library/axis-1_1/lib"/> ... <path > <fileset dir="${axis.lib.dir}"> <include name="**/*.jar"/> </fileset> </path> ... <target name="run-wsdl2java" description="Generates WS proxy code from WSDL"> <path > <path ref/> </path> <taskdef name="wsdl2java" classname="org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask"> <classpath ref/> </taskdef> <mkdir dir="${gen.source.dir}" /> <wsdl2java output="${gen.source.dir}" url="InventoryService.wsdl" verbose="true"> <mapping namespace="http://localhost:8080/jbossatwork-ws" package="com.jbossatwork.client"/> <mapping namespace="http://localhost:8080/jbossatwork-ws/types" package="com.jbossatwork.client"/> </wsdl2java> </target> The <run-wsdl2java> target uses the Axis <wsdl2java> task to generate the Web Service proxy objects (InventoryServiceLocator, InventoryService, and InventoryEndpoint) and custom data types (CarDTOArray and CarDTO) for the client. The <mapping>elements map the namespace from the WSDL to our Java package namecom.jbossatwork.client. The namespace for each <mapping> element comes from the WSDL:
The <mapping>elements coerce <wsdl2java> to generate the proxy and custom data type objects with a reasonable Java package name. Download Axis 1.1 from http://ws.apache.org/mirrors.cgi, and add the Axis JAR files to your CLASSPATH by doing one of the following:
After generating the Web Service proxy and custom data type objects, we then compile and use them in our client, as Example 10-15 demonstrates. Example 10-15. MyAxisClient.javapackage com.jbossatwork.client; public class MyAxisClient { public static void main(String [ ] args) { try { System.out.println("Finding InventoryService ...\n"); InventoryService service = new InventoryServiceLocator( ); System.out.println("Getting InventoryEndpoint ...\n"); InventoryEndpoint endpoint = service.getInventoryEndpointPort( ); System.out.println("Getting Cars ..."); CarDTOArray carDTOArray = endpoint.findAvailableCars( ); CarDTO[ ] cars = carDTOArray.getCars( ); for (int i = 0; i < cars.length; ++i) { System.out.println("Year = [" + cars[i].getModelYear( ) + "], Make = [" + cars[i].getMake( ) + "], Model = [" + cars[i].getModel( ) + "], status = [" + cars[i].getStatus( ) + "]"); } } catch(Exception e) { e.printStackTrace( ); } } } Axis does all the heavy lifting for us by encapsulating the low-level Web Service calls and custom data type serialization/deserialization. The proxy and custom data type objects generated by Axis are easy to use, so Web Service invocation looks just like calling a POJO. The Axis-generated code is elegant and looks natural to anyone accustomed to OO programming languages. The InventoryServiceLocator( ) constructor returns an InventoryService object that enables us to obtain an InventoryEndpoint, a remote handle for accessing the service. We then use the InventoryEndpoint object to access JAW Motors' car inventory by invoking our findAvailableCars( ) Web Service operation that returns a CarDTOArray. The CarDTOArray contains an array of CarDTO objects, so we call the CarDTOArray.getCars( ) method to extract the array of CarDTO objects. We finish by printing the contents of each CarDTO element in the array.
|