Setting up your web.xml

To set up CXF to use a Servlet you'll need to add the CXFServlet to your web.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
  <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <display-name>CXF Servlet</display-name>
    <servlet-class>
        org.apache.cxf.transport.servlet.CXFServlet
    </servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>
</web-app>

To create services that use this transport you can either use the CXF APIs (for instance, JAX-WS) or you can create an XML file which registers services for you.

Publishing an endpoint with XML

NOTE: this requires a snapshot from Feb 12 or later.

CXF uses Spring to provide XML configuration of services. This means that first we'll want to load Spring via a Servlet listener and tell it where oure XML configuration file is:

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		classpath:com/acme/ws/services.xml
	</param-value>
</context-param>

<listener>
	<listener-class>
		org.springframework.web.context.ContextLoaderListener
	</listener-class>
</listener>

NOTE: this is in the process of being simplified so will not have to add the ContextLoaderListener in future releases.

The next step is to actually write the configuration file:

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:jaxws="http://cxf.apache.org/jaxws"
      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/schema/jaxws.xsd">

  <import resource="classpath:META-INF/cxf/cxf.xml"/>
  <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
  <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

  <jaxws:endpoint id="greeter"
                  implementor="org.apache.hello_world_soap_http.GreeterImpl"
                  address="/Greeter1"/>
</beans>

Here we're creating a JAX-WS endpoint based on our implementation class, GreeterImpl.

NOTE: We're publishing this class at the address "http://localhost/mycontext/services/Greeter1". Since Servlets are not aware of their HTTP address, the Servlet will listen for requests on all available hosts/ports that it has been set up to listen on by its container.

Publishing an endpoint with the API

Once your Servlet is registered in your web.xml, you should not have to do anything special to make sure that CXF uses it as it's HTTP Transport. Simply publish with the related path "Greeter" and your service should appear at the address you specify:

Endpoint.publish("/Greeter", new GreeterImpl());

The one thing you must ensure is that your CXFServlet is set up to listen on that path. Otherwise the CXFServlet will never receive the requests.

Accessing the MessageContext and/or HTTP Request and Response

Sometimes you'll want to access more specific message details in your service implementation. One example might be accessing the actual request or response object itself. This can be done using the WebServiceContext object.

First, declare a private field for the WebServiceContext in your service implementation, and annotate it as a resource:

@Resource
private WebServiceContext context;

Then, within your implementing methods, you can access the MessageContext, HttpServletRequest, and HttpServletResponse as follows:

MessageContext ctx = context.getMessageContext();
HttpServletRequest request = (HttpServletRequest) ctx.get(AbstractHTTPDestination.HTTP_REQUEST);
HttpServletRequest response = (HttpServletResponse) ctx.get(AbstractHTTPDestination.HTTP_RESPONSE);

Of course, it is always a good idea to program defensively if using transport-specific entities like the HttpServletRequest and HttpServletResponse. If the transport were changed (for instance to the JMS transport), then these values would likely be null.