Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

This example will lead you through creating your first service with Spring. You'll learn how to:

  • Set up your build for CXF
  • Writing a simple JAX-WS service
  • Set up the HTTP transport

This example corresponds to the java_first_spring_support example in the CXF distribution.

Setting up your build

The use of Apache Maven is recommended for your web service projects, as it will automatically bring in all necessary dependencies for your web service project. See the Maven pom.xml for this sample for the configuration needed. All samples provided by CXF use Apache Maven, except for the antbuild sample which shows how you can build CXF projects with Apache Ant instead.

The mvn dependency:list and mvn dependency:tree commands from the Maven Dependency Plugin will show all dependencies used by your project.

Writing your Service

First we'll write our service interface. It will have one operation called "sayHello" which says "Hello" to whoever submits their name.

Wiki Markup
{snippet:id=service|lang=java|url=cxf/trunk/distribution/src/main/release/samples/java_first_spring_support/src/main/java/demo/spring/service/HelloWorld.java}

Our implementation will then look like this:

Wiki Markup
{snippet:id=service|lang=java|url=cxf/trunk/distribution/src/main/release/samples/java_first_spring_support/src/main/java/demo/spring/service/HelloWorldImpl.java}

The @WebService annotation on the implementation class lets CXF know which interface to use when creating WSDL. In this case its simply our HelloWorld interface.

Declaring your server beans

CXF contains support for "nice XML" within Spring 2.0. For the JAX-WS side of things, we have a <jaxws:endpoint> bean which sets up a server side endpoint.

Lets create a "cxf-servlet.xml" file in our WEB-INF directory which declares an endpoint bean:

Wiki Markup
{snippet:id=beans|lang=java|url=cxf/trunk/distribution/src/main/release/samples/java_first_spring_support/src/main/webapp/WEB-INF/cxf-servlet.xml}

If you want to reference a spring managed-bean, you can write like this:

Code Block
xml
xml
<bean id="hello" class="demo.spring.service.HelloWorldImpl" />

<jaxws:endpoint id="helloWorld" implementor="#hello" address="/HelloWorld" />

The bean uses the following properties:

  • id specifies the id of the bean in the Spring context.
  • implementor specifies the implementation class.
  • address specifies the location the service will be hosted. This should just be a related path. This is because CXF can't know the war name and the servlet container's listening port, CXF will update the endpoint address with the request url at the runtime.

To provide a bean name instead of a classname as an implementor, simply supply the bean-name prepended with "#", e.g. implementor="#myBean".

You can also do more sophisticated things with the <jaxws:endpoint> element like add nested tags to attach JAX-WS Handlers or CXF Interceptors to the service. For more on this see JAX-WS Configuration.

Setting up the Servlet

Since we're relying on the default "cxf-servlet.xml" file the default web.xml referenced by many samples can be used.

Alternatively, for arbitrarily named configuration files such as beans.xml, application-context.xml, etc. we can add the following elements:

  1. the Spring ContextLoaderLister. This starts Spring and explicitly loads the configuration file. We can specify where our file is via a context-param element.

An example:

Code Block
java
java
<web-app ...>
...
   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>WEB-INF/beans.xml</param-value>
   </context-param>

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

It is important to note that the address that you chose for your endpoint bean must be one your servlet listens on. For instance, if my Servlet was register for "/some-services/*" but my address was "/more-services/HelloWorld", there is no way CXF could receive a request.

Create a Client (Easy Way)

Just like the <jaxws:endpoint> used on the server side, there is a <jaxws:client> that can be used on the client side. You'll give it a bean name, the service interface, and the service URL, and it will create a bean with the specified name, implementing the service interface, and invoking the remote SOAP service under the covers:

Code Block
xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

    <jaxws:client id="helloClient"
                  serviceClass="demo.spring.HelloWorld"
                  address="http://localhost:9002/HelloWorld" />
</beans>

You can now inject that "helloClient" bean into any other Spring bean, or look it up from the Spring application context manually with code like this:

Code Block
java
java
ApplicationContext context = ...; // your Spring ApplicationContext
HelloWorld client = (HelloWorld) context.getBean("helloClient");

You can also do more sophisticated things with the <jaxws:client> element like add nested tags to attach JAX-WS Handlers or CXF Interceptors to the client. For more on this see JAX-WS Configuration.

Create a Client (More Manual Way)

CXF includes a JaxWsProxyFactory bean which create a client for you from your service interface. You simply need to tell it what your service class is (the HelloWorld interface in this case) and the URL of your service. You can then create a client bean via the JaxWsProxyFactory bean by calling it's create() method.

Here's an example:

Wiki Markup
{snippet:id=beans|lang=xml|url=cxf/trunk/distribution/src/main/release/samples/java_first_spring_support/src/main/resources/client-beans.xml}

If you were going to access your client you could now simply pull it out of the Spring context (or better yet, inject it into your application using Spring!):

Code Block
java
java
 
ApplicationContext context = ...; // your Spring ApplicationContext
HelloWorld client = (HelloWorld) context.getBean("client");

client code at http://svn.apache.org/repos/asf/cxf/trunk/distribution/src/main/release/samples/java_first_spring_support/src/main/java/demo/spring/client/Client.java

Note

Some usage scenarios will require more extensive configuration (and this is not the case with the <jaxws:client> syntax described above). For more information, see JAX-WS Configuration.

Advanced Steps

For more information on using Spring you may want to read the Configuration and Spring sections of the User's Guide.