Working with CXF Tool

Exclusive offer: get 50% off this eBook here
Apache CXF Web Service Development

Apache CXF Web Service Development — Save 50%

Develop and deploy SOAP and RESTful Web Services

$26.99    $13.50
by Naveen Balani | January 2010 | Open Source

The CXF framework provides various tools that assist developers in creating and invoking web services. CXF provides tools to create web service clients and web service implementations from WSDL files, to create SOAP binding and service definition from WSDL interfaces, to validate WSDL files, and to integrate with the popular Apache Maven software tool for build management. In this article by Naveen Balani, we will look at some of the commonly used CXF tools that assist in web service development. We will cover the following topic in this article:

  • Invoking web services using a Java client

Invoking a web service using the Java client

A web service exposes a set of operations over the network, typically via HTTP protocol. In order to invoke the web services, the web service client needs to know the following information:

  • What operations are exposed by the web service
  • The input and output message formats required to access the service operations
  • What protocol, for instance HTTP or JMS, to use to invoke the web service
  • The URL location of the web service

All of the above information is contained in the standard XML descriptor called WSDL (Web Service Description Language). The WSDL file provides a format contract between the web service provider and the web service client. The web service client typically inspects the WSDL file to determine what operations are exposed by the web service, what parameters need to be supplied to invoke the web service operation and to formulate the request, and invokes the web service over the supported protocol. Similarly, the web service clients need to write the code to inspect the response and convert it into the required format. CXF hides the complexity of creating web service clients by providing the WSDL to Java command line tool, which takes a WSDL file and generates client code. The client code can be used by developers with no changes to invoke the web services.

In this section, we will look at how to generate client code from an existing WSDL. For this example, we will take a real world scenario, where we will invoke a .NET service located over the Web using the Java client generated by the WSDL to Java tool. This shows the true power of web service interoperability, where applications implemented in different languages can communicate with each other.

The process of generating web service clients does not differ for web services implemented in different languages, as you generate web service clients from WSDL and XML Schema definitions.

Before invoking the .NET service, let's examine the WSDL to determine which operations are exposed by the web service.

Analyzing the service WSDL definition

We will invoke a publicly available .NET web service located at http://www.ignyte.com/webservices/ignyte.whatsshowing.webservice/moviefunctions.asmx?wsdl. This web service retrieves US Theaters and Movie Showtime information based on a valid US zip code and a radius supplied by the web service clients.

The .NET web service is a WS-I compliant web service.

The Web Services Interoperability Organization (WS-I), an open industry organization, was formed to promote web services interoperability across platforms, operating systems, and programming languages. One concrete product of WS-I is the Basic Profile. Basic Profile narrows the scope of specifications to a reasonable set of rules and guidelines that are best suited to help interoperability.

If you type in the given URL in the browser, you see the WSDL definition, as shown in the following screenshot:

Let's analyze the important sections of the WSDL file to get an understanding of which operations are exposed by the movie information web service and which message formats are required to invoke the web service.

The web service provides two operations, GetTheatersAndMovies and GetUpcomingMovies, as shown in listing below. For this article, we will focus on how to invoke the GetTheatersAndMovies operation. The GetTheatersAndMovies takes the GetTheatersAndMoviesSoapIn message as the input and provides GetTheatersAndMoviesSoapOut as the output message.

<wsdl:portType name="MovieInformationSoap">
<wsdl:operation name="GetTheatersAndMovies">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/
wsdl/">This method will retrieve a list of all theaters and the movies
playing today.</wsdl:documentation>
<wsdl:input message="tns:GetTheatersAndMoviesSoapIn" />
<wsdl:output message="tns:GetTheatersAndMoviesSoapOut" />
</wsdl:operation>
</wsdl:portType>

The web service client invokes the GetTheatersAndMovies operation to get theater and movie information. The input to the GetTheatersAndMovies operation is the GetTheatersAndMoviesSoapIn XML message.

The GetTheatersAndMoviesSoapIn message references the GetTheatersAndMovies element, which defines the actual XML schema definition for the input message. The following is the code listing of GetTheatersAndMovies schema definition:


<s:element name="GetTheatersAndMovies">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1"
name="zipCode" type="s:string" />
<s:element minOccurs="1" maxOccurs="1"
name="radius" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>

The GetTheatersAndMovies contains an element zipCode of type String and radius which is of type integer that needs to be passed as input by the web services client as an input to the GetTheatersAndMoviesSoapIn operation. The minOccurs and maxOccurs attribute associated with zipCode and radius is used to specify the minimum and maximum occurrence of the element inside a GetTheatersAndMovies element. The zipCode and radius element can appear only once inside a GetTheatersAndMovies element as it specifies the value of maxOccurs="1". If maxOccurs has the value Unbounded, then it implies that multiple occurrences of the element can exist.

Similarly, the GetTheatersAndMoviesResponse specifies the output message format for the response. The following is the code listing of the GetTheatersAndMoviesResponse schema definition. We will break down the schema for better understanding:

  • The GetTheatersAndMoviesResponse schema
    The following shows the definition of GetTheatersAndMoviesResponse. The GetTheatersAndMoviesResponse contains an element ArrayOfTheater.
    <s:element name="GetTheatersAndMoviesResponse">
    <s:complexType>
    <s:sequence>
    <s:element minOccurs="0" maxOccurs="1"
    name="GetTheatersAndMoviesResult" type=
    "tns:ArrayOfTheater" />
    </s:sequence>
    </s:complexType>
    </s:element>
  • The ArrayOfTheater Schema
    The following shows the definition of ArrayOfTheater schema.
    The ArrayOfTheater is an array which consists of Theatre elements.
    The maxOccurs="unbounded" specifies that multiple occurrences of Theatre elements can exist in an ArrayOfTheater element.

    <s:complexType name="ArrayOfTheater">
    <s:sequence>
    <s:element minOccurs="0" maxOccurs=
    "unbounded" name="Theater" nillable=
    "true" type="tns:Theater" />
    </s:sequence>
    </s:complexType>

  • The Theater Schema
    The Theater elements consist of the Name and Address elements of type String, which specifies the name and address of the Theater and an array of ArrayOfMovie element.
    <s:complexType name="Theater">
    <s:sequence>
    <s:element minOccurs="0" maxOccurs="1"
    name="Name" type="s:string" />
    <s:element minOccurs="0" maxOccurs="1"
    name="Address" type="s:string" />
    <s:element minOccurs="0" maxOccurs="1"
    name="Movies" type="tns:ArrayOfMovie" />
    </s:sequence>
    </s:complexType>
  • The ArrayOfMovie Schema
    The following is the ArrayOfMovie definition. The ArrayOfMovie is an array which consists of Movie elements. The maxOccurs="unbounded" specifies that multiple occurrences of Movie elements can exist in an ArrayOfMovie element.
    <s:complexType name="ArrayOfMovie">
    <s:sequence>
    <s:element minOccurs="0" maxOccurs=
    "unbounded" name="Movie" nillable=
    "true" type="tns:Movie" />
    </s:sequence>
    </s:complexType>
  • The Movie Schema
    The Movie element contains details of movies such as ratings, names of the movies, running times and show times represented as String type.
    <s:complexType name="Movie">
    <s:sequence>
    <s:element minOccurs="0" maxOccurs="1"
    name="Rating" type="s:string" />
    <s:element minOccurs="0" maxOccurs="1"
    name="Name" type="s:string" />
    <s:element minOccurs="0" maxOccurs="1"
    name="RunningTime" type="s:string" />
    <s:element minOccurs="0" maxOccurs="1"
    name="ShowTimes" type="s:string" />
    </s:sequence>
    </s:complexType>

Based on the Schema definitions above, the CXF WSDL2Java tool generates Java code that maps to these XML elements. The web service clients communicate with the web services using these generated Java objects to invoke a Java method representing the GetTheatersAndMoviesoperation and leave the SOAP XML to Java conversion and low level implementation details with the CXF framework.

The SOAP address in the WSDL file specifies the location of the service, which is http://www.ignyte.com/webservices/ignyte.whatsshowing.webservice/moviefunctions.asmx, as shown in the listing below:

 <wsdl:service name="MovieInformation">
<wsdl:port name="MovieInformationSoap" binding=
"tns:MovieInformationSoap">
<soap:address location="http://www.ignyte.com/webservices/
ignyte.whatsshowing.webservice/moviefunctions.asmx" />
</wsdl:port>
<wsdl:port name="MovieInformationSoap12" binding=
"tns:MovieInformationSoap12">
<soap12:address location="http://www.ignyte.com/webservices/
ignyte.whatsshowing.webservice/moviefunctions.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

We will now look at how to generate the web service client code for the Movie information web service.

Building and running the Java web service clients

The source code and build files for the example are available in the wsdl2Java folder of the downloaded source code. We will follow the steps below to build and execute the web service client:

  • Generate the web service clients
  • Analyze the generated artifacts
  • Modify the generated code
  • Build the web service client
  • Run the web service client

Generate the web service clients

We will use the Ant build script (build.xml) for generating the web service client code and building the project code as shown below. Navigate to the wsdl2java folder of the downloaded source code. Execute the cxfWSDLToJava target by navigating to the wsdl2java folder and running the following command:

ant cxfWSDLToJava

The following figure shows the output generated upon running the ant command:

The cxfWSDLToJava ant target calls the CXF tool apache.cxf.tools.wsdlto.WSDLToJava to generate web service client code based on the URL http://www.ignyte.com/webservices/ignyte.whatsshowing.webservice/moviefunctions.asmx?wsdl

The following is a code snippet of ant target cxfWSDLToJava in build.xml:


<target name="cxfWSDLToJava">
<java classname="org.apache.cxf.tools.wsdlto.WSDLToJava"
fork="true">
<arg value="-client"/>
<arg value="-d"/>
<arg value="src"/>
<arg value="http://www.ignyte.com/webservices/ignyte.
whatsshowing.webservice/moviefunctions.asmx?wsdl"/>
<classpath>
<path refid="cxf.classpath"/>
</classpath>
</java>
</target>

WSDLToJava generates JAX-WS compliant Java code for the services defined in the WSDL document. Based on the parameters passed, it can generate the starting point of the code for developing the web service client and service. The client option, as shown in above snippet, generates the client code. The following is a list of augments and descriptions supported by the WSDLToJava tool extracted as it is from the CXF website—http://cwiki.apache.org/CXF20DOC/wsdl-to-java.html

Apache CXF Web Service Development Develop and deploy SOAP and RESTful Web Services
Published: December 2009
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

Option

Description

-?

Displays the online help for this utility.

-help

Displays the online help for this utility.

-h

Displays the online help for this utility.

-fe frontend-name

Specifies the frontend technology to use for generating code. Default is JAXWS. Currently supports only JAXWS frontend.

-db databinding-name

Specifies the databinding mechamsim. Default is jaxb. Currently supports jaxb and xmlbeans databinding. sdo (sdo-static and sdo-dynamic) supported in 2.3.

-wv wsdl-version

Specifies the wsdl version .Default is WSDL1.1. Currently supports only WSDL1.1 version.

-p [ wsdl-namespace= ] PackageName

Specifies zero, or more, package names to use for the generated code. Optionally specifies the WSDL namespace to package name mapping.

-sn service-name

The WSDL service name to use for the generated code.

-b binding-name

Specifies JAXWS or JAXB binding files or XMLBeans context files. Use multiple -b flags to specify multiple entries.

-catalog catalog-file-name

Specify catalog file to map the imported wsdl/schema

-d output-directory

Specifies the directory into which the generated code files are written.

-compile

Compiles generated Java files.

-classdir complile-class-dir

Specifies the directory into which the compiled class files are written.

-client

Generates starting point code for a client mainline.

-server

Generates starting point code for a server mainline.

-impl

Generates starting point code for an implementation object.

-all

Generates all starting point code: types, service proxy, service interface, server mainline, client mainline, implementation object, and an Ant build.xml file.

-ant

Generates the Ant build.xml file.

-autoNameResolution

Automatically resolve naming conflicts without requiring the use of binding customizations.

-defaultValues=[DefaultValueProvider impl]

Specifies that default values are generated for the impl and client. You can also provide a custom default value provider. The default provider is RandomValueProvider

-nexclude schema-namespace [=java-packagename]

Ignore the specified WSDL schema namespace when generating code. This option may be specified multiple times. Also, optionally specifies the Java package name used by types described in the excluded namespace(s).

-exsh (true/false)

Enables or disables processing of implicit SOAP headers (i.e. SOAP headers defined in the wsdl:binding but not wsdl:portType section.) Default is false.

-dns (true/false)

Enables or disables the loading of the default namespace package name mapping. Default is true and http://www.w3.org/2005/08/addressing=org.apache.cxf.ws.addressing namespace package mapping will be enabled.

-dex (true/false)

Enables or disables the loading of the default excludes namespace mapping. Default is true.

-validate

Enables validating the WSDL before generating the code.

-keep

Specifies that the code generator will not overwrite any preexisting files. You will be responsible for resolving any resulting compilation issues.

-wsdlLocation wsdlLocation

Specifies the value of the @WebServiceClient annotation's wsdlLocation property.

-xjc<xjc args>

Specifies a comma separated list of arguments that are passed directly to the XJC processor when using the JAXB databinding. A list of available XJC plugins can be obtained using -xjc-X.

-noAddressBinding

For compatibility with CXF 2.0, this flag directs the code generator to generate the older CXF proprietary WS-Addressing types instead of the JAX-WS 2.1 compliant WS-Addressing types.

-v

Displays the version number for the tool.

-verbose

Displays comments during the code generation process.

-quiet

Suppresses comments during the code generation process.

wsdlfile

The path and name of the WSDL file to use in generating the code.

After executing the command, the generated code is created in the wsdl2java/src folder.

Analyzing the JAX-WS and client generated artifacts

The following artifacts are generated in the wsdl2Java/src/com/ignite/whatsshowing folder:

  • JAXB classes— these are generated by reading the schema definitions defined in the Movie information WSDL. The classes generated for the Movie information web service are ArrayOfMovie, ArrayOfTheater, ArrayOfUpcomingMovie, Movie, Theater UpcomingMovie, and ObjectFactory.
  • The RequestWrapper and ResponseWrapper classes—as the Movie information web service uses the document-literal web service style, the Request and Response wrapper objects are generated for input and output message formats for the operations GetTheatersAndMovies and GetUpcomingMovies. The Request and Response Wrapper objects wrap the input and output for document-literal wrapped style web services. The GetTheatersAndMovies (Request Wrapper) and GetTheatersAndMoviesResponse (Response Wrapper) are generated for the getTheatersAndMovies operation.
  • The next code snippet shows the generated GetTheatersAndMovies.java. As you can see below, the class has JAXB annotations that are defined to map Java to an XML element. The @XmlRootElement defines the root element of the input request which has the name GetTheatersAndMovies. The attributes zipCode and radius are contained in the GetTheatersAndMovies XML element. The annotations are used to map Java to an XML request.
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"month",
"year"
})
@XmlRootElement(name = "GetTheatersAndMovies")
public class GetTheatersAndMovies {
protected String zipCode;
protected int radius;
public String getZipCode() {
return zipCode;
}
public void setZipCode(String value) {
this.zipCode = value;
}
public int getRadius() {
return radius;
}
public void setRadius(int value) {
this.radius = value;
}
}

  • Service Interface—this class contains the service interface for the Movie information web service. The service interface generated for the Movie information web service is MovieInformationSoap.java.
  • Service class—this is the class that web service clients will use to make requests to the web service. The service class generated for the Movie information web service is MovieInformation.java. The service class contains the @WebServiceClient annotation and lookup methods to retrieve the Service Interface.
  • Client code— the standalone web service client code that provides a starting point for the client code, which calls various operations of the web service. You need to modify the client code to provide the input for each of the operations being invoked. The client code generated for the Movie information web service is MovieInformationSoap_MovieInformationSoap12_Client.java and MovieInformationSoap_MovieInformationSoap_Client.java. Two client codes are generated as there are two ports defined for the Movie information service, MovieInformationSoap and MovieInformationSoap12. You can use any of the client code. There are two port types provided to support SOAP 1.1 and SOAP 1.2 request.

Modifying the generated client

We will now modify the generated client MovieInformationSoap_MovieInformationSoap12_Client.java to provide input to the getTheatersAndMovies operations method. Open the MovieInformationSoap_MovieInformationSoap12_Client.java in any text editor, and modify the generated code, as highlighted in bold.

package com.ignyte.whatsshowing;
import java.io.File;
//Other imports…..
import java.util.List;
public final class MovieInformationSoap_MovieInformationSoap12_Client
{
public static void main(String args[]) throws Exception {
//Refer to generated code for compete listing
System.out.println("Invoking getTheatersAndMovies...");
java.lang.String _getTheatersAndMovies_zipCode = "78750";
int _getTheatersAndMovies_radius = 2;
com.ignyte.whatsshowing.ArrayOfTheater _getTheatersAndMovies__
return = port.getTheatersAndMovies(_getTheatersAndMovies_zipCode, _
getTheatersAndMovies_radius);
System.out.println("getTheatersAndMovies.result=" + _
getTheatersAndMovies__return);
System.out.println("Theater List is : "
+ _getTheatersAndMovies__return.getTheater().size());
List<Theater> theatreList = _getTheatersAndMovies__return.
getTheater();
for (int i = 0; i < theatreList.size(); i++) {
System.out.println("Theatre Name : " +
theatreList.get(i).getName());
List<Movie> movieList =
theatreList.get(i).getMovies().getMovie();
for (int j = 0; j < movieList.size(); j++) {
System.out.println("Movie Name : " +
movieList.get(j).getName());
System.out.println("Movie Rating : " +
movieList.get(j).getRating());
}
System.out.println("End of Movies for Theatre :"
+ theatreList.get(i).getName());
}
//Remaining code block

As you can see in the previous code, we specify the zip code as 78750 and radius as 2. Next, the operation getTheatersAndMovies(_getTheatersAndMovies_zipCode, _getTheatersAndMovies_radius) is invoked. The operation returns the com.ignyte.whatsshowing.ArrayOfTheater response. We then get the list of theatres from com.ignyte.whatsshowing.ArrayOfTheater object by calling the _getTheatersAndMovies__return.getTheater() method. Next we iterate through the theatreList and print the name, theatreList.get(i).getName(). For each theatre, we retrieve the list of movies running in that theatre, by calling theatreList.get(i).getMovies().getMovie(). We then iterate through the set of movies and print the name, movieList.get(j).getName() and rating, movieList.get(j).getRating() for each movie.

Building the client

To build the client, navigate to the wsld2java folder, and run the following command to build the code:

ant build

The following screenshot shows the output generated on running the ant command:

Running the client

To run the client, navigate to the wsld2java folder, and run the following command to build the code:

ant runClient

This command calls the target runClient in build.xml, and executes the MovieInformationSoap_MovieInformationSoap_Client class.

The following output will be printed on the console. Look for the Theater List is system output message to determine how many theatres are retrieved for that area code. For each theatre you see the movie information being printed on the console. Look for the Movie Name and Movie Rating system output message, as shown in the next screenshot. Note that this information is retrieved at runtime, so the value of Theater List is would vary from the one shown in the screenshot below:

We have thus successfully invoked the Movie information web service.

Summary

In this article we looked at how to:

  • Utilize CXF tools for web services development
  • Create Java web service clients from WSDL and invoke real world web services

If you have read this article you may be interested to view :

Apache CXF Web Service Development Develop and deploy SOAP and RESTful Web Services
Published: December 2009
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


Naveen Balani

Naveen Balani works as a Software Architect with WebSphere Business Services Fabric (WBSF) Product out of IBM India Software Labs, Mumbai. He has over 9 years of industrial experience and has architected and implemented large scale BPM solutions. He started working with Web Services way back in 2001 and proposed the first MVC web services-based pattern (http://www.ibm.com/developerworks/library/ws-mvc/) in 2002. He is a Master Author with IBM developer works having published over 60 publications. He has co-authored books on Spring framework (published by Wrox) and Multiple IBM Redbooks on WebSphere Business Services Fabric and BPM 6.2 Product deployments.

Books From Packt

GlassFish Administration
GlassFish Administration

JBoss AS 5 Development
JBoss AS 5 Development

Plone 3 for Education
Plone 3 for Education

ADempiere 3.4 ERP Solutions
ADempiere 3.4 ERP Solutions

Apache Roller 4.0 – Beginner's Guide
Apache Roller 4.0 – Beginner's Guide

Beginning OpenVPN 2.0.9
Beginning OpenVPN 2.0.9

MooTools 1.2 Beginner's Guide
    MooTools 1.2 Beginner's Guide

Funambol Mobile Open Source
Funambol Mobile Open Source

No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
x
P
j
9
5
E
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software