CXF is another web services stack from the Apache Software Foundation, the same group behind the Axis2 stack. Even though they come from the same organization, Axis 2 and CXF take very different approaches to how web services are configured and delivered. In this article, you'll learn the basics of using JAXB 2.x and JAX-WS 2.x for web services work with CXF, and you'll see how CXF compares to the other JAXB/JAX-WS stacks — Axis2 and Metro — discussed in prior articles.
In terms of the user interface, CXF has a lot in common with the Axis2 and Metro web service stacks. All three stacks allow you either to start from existing Java™ code and build a web service, or start from a WSDL web service description and generate Java code to use or implement the service. And like the other stacks, CXF models service operations as method calls and service port types as interfaces.
Like Axis2, but unlike Metro, CXF allows you to choose between different data-binding technologies. CXF support for JAXB 2.x data binding is on par with Metro and superior to Axis2 because it allows you to use JAXB customizations when generating code from WSDL (Axis2 does not). CXF also lets you use other data-binding approaches, though the support for them is not as well developed as in Axis2 — in particular, you can generate code from WSDL with CXF only if you're using JAXB or XMLBeans data binding.
The preferred service-configuration technique (or frontend, in CXF terminology) used with CXF is JAX-WS 2.x annotations, generally supplemented by XML configuration files. Support for JAX-WS annotations in CXF is on par with Metro, making it much better suited for JAX-WS use than Axis2 (which has some major limitations in using JAX-WS, as discussed in "JAXB and JAX-WS in Axis2"). As with other JAX-WS implementations, CXF requires the service WSDL to be available to the client at run time.
Like the other stacks, CXF uses request and response processing flows composed of configurable components. CXF calls the components intercepters, rather than handlers, but terminology aside these are equivalent components. Like Metro, CXF comes complete with support for WS-Security and other extension technologies as part of the basic download. Unlike Metro, the CXF JARs are modular — meaning you can pick and choose the JARs to include as part of your application depending on the technologies being used (the /lib/WHICH_JARS file in the CXF installation tells you the particular JARs needed for various common use cases). The downside of this modularity is that you can end up with a long list of specific JARs needed for your application; on the plus side, it allows you to keep down the size of your deployment.
Again like Metro, CXF normally requires you to build a WAR file for your web service rather than deploying potentially many services to a single server installation (the approach used with Axis2). CXF also provides an integrated HTTP server suitable for production use in the form of the Jetty server. This gives you a more flexible and powerful alternative than the simple HTTP server support integrated in Axis2 and Metro.
The code download provides a version of the simple library-management service used in previous articles of this series; this one is modified to demonstrate CXF usage. As with the earlier versions, the WSDL service definition defines four operations:
getBookretrieves the details for a particular book identified by International Standard Book Number (ISBN).
getBooksByTyperetrieves the details for all books of a particular type.
getTypesfinds the types of books available.
addBookadds a new book to the library.
In "JAXB and JAX-WS in Axis2," you saw how this application worked in Axis2, then in "Introducing Metro," you saw it in Metro. Most of the discussion in the earlier articles also applies to using CXF. The WSDL is identical except for the service name and endpoint address; the generated JAXB data model is the same, and even the generated service classes are identical except for the Java package and the service name used in the JAX-WS annotations.
Client-side code for the sample application on CXF is identical to using JAX-WS with Axis2 or Metro, and the build steps are very similar: just use the CXF wsdl2java tool in place of the JAX-WS reference implementation wsimport tool. See "JAXB and JAX-WS in Axis2" for details of the code and handling.
Although the client code is the same, there's one significant difference in the client
behavior with CXF. By default, CXF prints out an obnoxious amount of logging details
to the console. CXF uses Java Logging, so to
avoid this output, you need to set a system property to point to a logging properties file with settings changed to output only
SEVERE information. The Ant build.xml for the sample application does this using the JVM parameter line
The server-side code for the sample application on CXF is also identical to using JAX-WS with Axis2 or Metro, and the build process is very similar to Metro. With Axis2, you prepare the service for deployment by creating a JAR file containing the service and data model classes, then deploy the service by dropping that JAR into the WEB-INF/servicejars directory in an Axis2 server installation. With Metro and CXF, you instead need to create a WAR file containing the service and data model classes, the Metro or CXF library JARs, and a pair of configuration files (one of which is named differently in the two stacks). The WEB-INF/web.xml file configures the actual servlet handling. The version used for the sample application is shown in Listing 1:
Listing 1. Sample application web.xml
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"> <display-name>CXFLibrary</display-name> <description>CXF Library Service</description> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:META-INF/cxf/cxf.xml classpath:META-INF/cxf/cxf-extension-soap.xml classpath:META-INF/cxf/cxf-servlet.xml </param-value> </context-param> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
The Listing 1 WEB-INF/web.xml file is just a standard servlet configuration file, telling the web application server (such as Tomcat) how to interface to the servlet application. The details are similar to those in the Metro example, though for CXF the
<servlet-class> is part of the CXF code and the
<listener-class> references a Spring Framework class (see Resources). As with the Metro example, the servlet is configured to process all requests coming to this web application (by the
A separate file, WEB-INF/cxf-servlet.xml, is used to configure CXF to route requests received by the servlet to the service-implementation code and to supply the service WSDL on-demand. This file is shown in Listing 2:
Listing 2. Sample application cxf-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:soap="http://cxf.apache.org/bindings/soap" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:endpoint id="Processor" implementor="com.sosnoski.ws.library.cxf.CXFLibraryImpl" wsdlLocation="WEB-INF/wsdl/library.wsdl" address="/"> </jaxws:endpoint> </beans>
The Listing 2 WEB-INF/cxf-servlet.xml file defines a single endpoint with an implementation class, the pattern to be matched for requests, and a WSDL document location. The WSDL document location is the only optional part of this endpoint definition. If you don't specify a WSDL for a service endpoint in the cxf-servlet.xml file, CXF automatically generates one at run time based on the JAX-WS annotations.
Before you can try out the sample code, you need to download and install a current version of CXF on your system (see Resources). The sample code was tested with the 2.2.5 release. You also need to edit the build.properties file in the root directory of the unzipped sample-code download to change the value of the
cxf-home property to the path to your CXF installation. If you're going to be testing with a server on a different system or port, you may need to change the
To build the sample application using the supplied Ant build.xml, open a console to the root directory of the download code and type
ant. This will first invoke the CXF
wsdl2java tool (included in the CXF distribution), then compile the client and server, and finally package the server code as a WAR. You can then deploy the generated cxf-library.war file to your test server, and finally type
ant run on the console to try running the sample client. The sample client runs through a sequence of several requests to the server, printing brief results for each request. As mentioned in Client-side usage, the build configures CXF logging to avoid printing configuration details when running the sample client.
Notice the use of Spring Framework bean configurations in the Listing 2 cxf-servlet.xml configuration file. Spring, as you may know, is an open source application framework that includes many component libraries you can use to assemble your applications. The Inversion of Control (IoC) container is the original basis of the Spring Framework. It allows you to link and configure JavaBean-style software components, using Java reflection to access properties of the bean objects at run time.
The Spring IoC container normally uses XML files for the dependency information, and the cxf-servlet.xml file in Listing 2 is an example of such a Spring configuration. The
<beans> element is just a wrapper around individual bean configurations. The
<jaxws:endpoint> element is such a bean, one that CXF associates with a particular type of object (a
You can specify many other options in the cxf-servlet.xml file beyond those used in this simple example, including message-flow configuration for a service. See the JAX-WS configuration information in the CXF documentation for full details (under Frontends/JAX-WS).
Aside from JAX-WS annotations, Spring is used for all configuration of the CXF stack, including the organization of message flows internal to CXF. Most of the time these configuration details are handled automatically, using XML configuration files included directly in the CXF JARs (see the
contextConfigLocation parameter value in the Listing 1 web.xml file to see how these are referenced), but you can override or add to the common flows using your own configuration files. That's not going to be covered directly in this series of articles; you can see the CXF documentation for details.
In this article you've seen the basics of using JAXB 2.x data binding and JAX-WS 2.x annotation-based configuration with the CXF web services stack. The same JAXB/JAX-WS code used in earlier articles with the Axis2 and Metro stacks also works in CXF, after only minor changes to the build and using a different deployment-configuration file. This cross-stack compatibility is the main benefit of using JAXB and JAX-WS, since it makes it easy for you to switch between stacks.
There's a lot more to CXF than this simple example shows, and in future articles you'll find out about some of the other features. The next article will look at using WS-Security, so you can see how the CXF implementation compares with Axis2 and Metro.
|Source code for this article||j-jws12.zip||16KB||HTTP|
Apache CXF: Visit the site for CXF, an open source web services stack from the Apache Software Foundation.
Spring Framework: Spring is the starting point for many kinds of development.
"Design and implement POJO Web services using Spring and Apache CXF, Part 1: Introduction to Web services creation using CXF and Spring" (Rajeev Hathi and Naveen Balani, developerWorks July 2008): This article shows you how to use CXF for Java-first web service development with JAXB and JAX-WS.
"Design and develop JAX-WS 2.0 Web services" (Rajeev Hathi and Naveen Balani, developerWorks, September 2007): This tutorial shows how to develop Java-first web services using the JAXB and JAX-WS support bundled in Java 6 SE.
JAX-WS Reference Implementation: Here's the home page for the JAX-WS reference implementation.
technology bookstore for books on these and other technical topics.
developerWorks Java technology zone: Find hundreds of articles about every aspect of Java programming.
Get products and technologies
- CXF: Download CXF.
Apache CXF mailing lists: Subscribe or browse the archives.
- Get involved in the My developerWorks community.
Dennis Sosnoski is a consultant and trainer specializing in Java-based XML and Web services. His professional software development experience spans more than 30 years, with the last 10 focused on server-side XML and Java technologies. Dennis is the lead developer of the open source JiBX XML Data Binding framework and the associated JiBX/WS Web services framework, as well as a committer on the Apache Axis2 Web services framework. He was also one of the Expert Group members for the JAX-WS 2.0 and JAXB 2.0 specifications. The material for the Java Web Services series is based on Dennis' training classes.