You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 14 Next »

CXF includes a simple frontend which builds services from reflection. This is in contrast to the JAX-WS frontend which requires you to annotate your services. The simple frontend will use reflection to intelligently map your classes to a WSDL model.

By default CXF uses the JAXB databinding. If you are interested in a databinding which does not require annotations, please see the documentation on the Aegis Databinding.

ServerFactoryBean

The ServerFactoryBean produces a Server instance for you. It requires a service class and an address to publish the service on. By creating a Server you'll have started your service and made it available to the outside world.

First you'll want to create your service class:

public interface HelloWorld {
  String sayHi(String text);
}

This does not have to be an interface, but we're going to use an interface for this example because

  1. It is good to separate out your service contract (your interface) from your implementation
  2. This allows us to easily create a Java Proxy client

We'll also need an implementation class:

public class HelloWorldImpl implements HelloWorld {
  public String sayHi(String text) {
    return "Hello " + text;
  }
}

And now we'll want to create a Server from this

import org.apache.cxf.frontend.ServerFactoryBean;
...

// Create our service implementation
HelloWorldImpl helloWorldImpl = new HelloWorldImpl();

// Create our Server
ServerFactoryBean svrFactory = new ServerFactoryBean();
svrFactory.setServiceClass(HelloWorld.class);
svrFactory.setAddress("http://localhost:9000/Hello");
svrFactory.setServiceBean(helloWorldImpl);
svrFactory.create();

Your service is now started! You can access the wsdl at "http://localhost:9000/Hello?wsdl".

ClientProxyFactoryBean

You'll also want to create a client for your service. CXF includes a ClientProxyFactoryBean which will create a Java proxy for you from your interface which will invoke the service.

import demo.hw.server.HelloWorld;
import org.apache.cxf.frontend.ClientProxyFactoryBean;
...

ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
factory.setServiceClass(HelloWorld.class);
factory.setAddress("http://localhost:9000/Hello");
HelloWorld client = (HelloWorld) factory.create();

You simply need to set your service class and your service's URL on the bean. Calling create() will then create a proxy for you based on your interface.

Configure with Spring

The XML configuration for do-it-yourself Spring beans and cxf.xml or cxf-servlet.xml are all very similiar.
The simple front-end does not have its own extension, so you don't need any extra imports if are setting up your
own application context.

Here's an example cxf-servlet.xml with simple front end endpoint configuration. If you use your own application context, you'll need to import the soap extension and http servlet extension.

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

  <simple:server id="pojoservice" serviceClass="demo.hw.server.HelloWorld" address="/hello_world">
  	<simple:serviceBean>
  		<bean class="demo.hw.server.HelloWorldImpl" />
  	</simple:serviceBean>
  </simple:server>
</beans>

The simple:server element supports many additional attributes:

Name

Value

endpointName

The endpoint name this service is implementing, it maps to the wsdl:port@name. In the format of "ns:ENDPOINT_NAME" where ns is a namespace prefix valid at this scope.

serviceName

The service name this service is implementing, it maps to the wsdl:service@name. In the format of "ns:SERVICE_NAME" where ns is a namespace prefix valid at this scope.

wsdlLocation

The location of the WSDL. Can be on the classpath, file system, or be hosted remotely.

bindingId

The binding uri for the service model to use

transportId

The transport uri which is used for looking up the transport factory in CXF

address

The service publish address

bus

The bus name that will be used in the jaxws endpoint.

serviceBean

The implementor of jaxws endpoint. You can specify the implementor class name here, or just the ref bean name in the format of "#REF_BEAN_NAME"

serviceClass

The implementor class name, it is really useful when you specify the implementor with the ref bean which is wrapped by using Spring AOP

start

Whether the service endpoint should be published now, or whether it will be published at a later point

It also supports many child elements:

Name

Value

simple:executor

A Java executor which will be used for the service. This can be supplied using the Spring <bean class="MyExecutor"/> syntax.

simple:inInterceptors

The incoming interceptors for this endpoint. A list of <bean>s or <ref>s.

simple:inFaultInterceptors

The incoming fault interceptors for this endpoint. A list of <bean>s or <ref>s.

simple:outInterceptors

The outgoing interceptors for this endpoint. A list of <bean>s or <ref>s.

simple:outFaultInterceptors

The outgoing fault interceptors for this endpoint. A list of <bean>s or <ref>s.

simple:properties

A properties map which should be supplied to the JAX-WS endpoint. See below.

simple:dataBinding

You can specify the which DataBinding will be use in the endpoint , This can be supplied using the Spring <bean class="MyDataBinding"/> syntax.

simple:binding

You can specify the BindingFactory for this endpoint to use. This can be supplied using the Spring <bean class="MyBindingFactory"/> syntax.

simple:features

The features that hold the interceptors for this endpoint. A list of <bean>s or <ref>s

simple:invoker

The invoker which will be supplied to this endpoint. This can be supplied using the Spring <bean class="MyInvoker"/> syntax.

simple:schemaLocations

The schema locations for endpoint to use. A list of <schemaLocation>s

simple:serviceFactory

The service factory for this endpoint to use. This can be supplied using the Spring <bean class="MyServiceFactory"/> syntax

simple:serviceBean

The service implementation instance to be used. This can be supplied using the Spring <bean class="MyServiceBean"/> syntax

Here is a more advanced example which shows how to provide interceptors and properties:

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

    <simple:server id="inlineInvoker" 
    serviceClass="org.apache.cxf.service.factory.HelloServiceImpl"
    address="http://localhost:8080/simpleWithAddress">
    <simple:invoker>
      <bean class="org.apache.cxf.service.invoker.BeanInvoker">
        <constructor-arg>
          <bean class="org.apache.cxf.service.factory.HelloServiceImpl"/>
        </constructor-arg>
      </bean>
    </simple:invoker>    
  </simple:server>
  
  <simple:server id="inlineSoapBinding" 
    serviceClass="org.apache.cxf.service.factory.HelloService"
    serviceBean="#greeter"
    address="http://localhost:8080/test"   
    serviceName="t:HelloService"
    xmlns:t="http://apache.org/hello_world_soap_http"
    endpointName="t:HelloPort"
    >
    <simple:binding>
      <soap:soapBinding mtomEnabled="true" version="1.2"/>
    </simple:binding>
  </simple:server>
</beans>

Configure with Spring for the simple front end client

You could use the <simple:client> element to configure the simple front end client, you can use the spring's getBean API to get the client instance from the application context.

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

  <simple:client id="client" 
    serviceClass="org.apache.cxf.service.factory.HelloService"
    address="http://localhost:9000/foo2"
    serviceName="s:XMLService"
    xmlns:s="http://apache.org/hello_world_soap_http"
    endpointName="s:XMLPort"    
    bindingId="http://cxf.apache.org/bindings/xformat"/>
</beans>

The simple:client element supports many additional attributes:

Name

Value

endpointName

The endpoint name this service is implementing, it maps to the wsdl:port@name. In the format of "ns:ENDPOINT_NAME" where ns is a namespace prefix valid at this scope.

serviceName

The service name this service is implementing, it maps to the wsdl:service@name. In the format of "ns:SERVICE_NAME" where ns is a namespace prefix valid at this scope.

wsdlLocation

The location of the WSDL. Can be on the classpath, file system, or be hosted remotely.

bindingId

The binding uri for the service model to use

address

The service publish address

bus

The bus name that will be used in the jaxws endpoint.

serviceClass

The implementor class name, it is really useful when you specify the implementor with the ref bean which is wrapped by using Spring AOP

username

The user name which is used in the transport layer

password

The password that is used in the transport layer

It also supports many child elements:

Name

Value

simple:inInterceptors

The incoming interceptors for this endpoint. A list of <bean>s or <ref>s.

simple:inFaultInterceptors

The incoming fault interceptors for this endpoint. A list of <bean>s or <ref>s.

simple:outInterceptors

The outgoing interceptors for this endpoint. A list of <bean>s or <ref>s.

simple:outFaultInterceptors

The outgoing fault interceptors for this endpoint. A list of <bean>s or <ref>s.

simple:properties

A properties map which should be supplied to the JAX-WS endpoint. See below.

simple:dataBinding

You can specify the which DataBinding will be use in the endpoint , This can be supplied using the Spring <bean class="MyDataBinding"/> syntax.

simple:binding

You can specify the BindingFactory for this endpoint to use. This can be supplied using the Spring <bean class="MyBindingFactory"/> syntax.

simple:features

The features that hold the interceptors for this endpoint. A list of <bean>s or <ref>s

simple:conduitSelector

The conduit selector which is strategy for retreival of a conduit to mediate an outbound message to be injected into the client.

Here is a more advanced example which shows how to provide interceptors and properties:

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

  <bean id="saajIn" class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
  <bean id="saajOut" class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
  
  <simple:client id="client1" 
    serviceClass="org.apache.cxf.service.factory.HelloService"
    address="http://localhost:9000/foo"
    serviceName="s:SOAPService"
    xmlns:s="http://apache.org/hello_world_soap_http">
    <simple:binding>
      <soap:soapBinding mtomEnabled="true" version="1.2"/>
    </simple:binding>
    <simple:inInterceptors>
	  <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
	  <ref bean="saajIn"/>
	</simple:inInterceptors>
	<simple:outInterceptors>
	  <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
	  <ref bean="saajOut"/>
	</simple:outInterceptors>
    <simple:conduitSelector>
      <bean class="org.apache.cxf.endpoint.NullConduitSelector"/>
    </simple:conduitSelector>
  </simple:client>
</beans>

Deploying Simple FrontEnd service to a container

If you are looking to deploy the service to a container follow the steps in "Transports->HTTP Transport -> Servlet Transport" section from the Table of contents. Add the xml content from the above section "Configure cxf-servlet.xml". Name your configuration file as say services.xml. Do not name it as cxf-servlet.xml.
You need to add the import statements from the sample configuration file in "Transports->HTTP Transport -> Servlet Transport"

Well-Known Issue

There is a known issue for the JAXB data binding with POJO, please see Dan Kulp's comment in https://issues.apache.org/jira/browse/CXF-897 .
If you want to use JAXB binding you should use the JAX-WS Frontend. Mixing Simple Frontend and JAXB binding leads to problems. The article A simple JAX-WS service shows a code first JAX-WS service that is almost as easy to use as the Simple Frontend.

  • No labels