XFire

Home
Bug/Issue Reporting
Download
FAQ
Get Involved
License
News
Stack Comparison
Support
User's Guide
XFire Team

M5

Javadocs
Reports

M6-SNAPSHOT

Javadocs
Reports

Developers

Developer Space
CVS
Building
Architecture
Interesting Projects
Release Process

One of XFire's core strengths is how embeddable it is. It is possible for a project to embed xfire and provide soap services without end users having to specify any XFire specific information. All configuration can be programatically driven, and it is possible to define your own service files to define services and any other configuration information.

This document will outline a number of typical scenarios for embedding. The first and most basic of these is the need to expose a java class as a service programatically.

The steps involved in this are:

  • Create an ObjectServiceFactory
  • Register the bean
  • Expose xfire

Details

The ObjectServiceFactory is responsible for creating service objects. It's an implementation of ServiceFactory that is used for POJO (javabean) style classes. The factory will introspect the specified class and expose all the methods available to it. By default, methods inherited from java.lang.Object are excluded (eg, hashCode, toString, and so on, since it doesn't really make sense to incur the overhead of a remote call for them.)

So let's create the factory:

//first we create a XFire instance, using the default implementation
//you can register your own implementation via XFireFactory.registerFactory()
XFire xfire = XFireFactory.newInstance().getXFire();
//the default transport manager handles a number of transport mechanisms,
//which is good enough for our needs
ServiceFactory factory = new ObjectServiceFactory(xfire.getTransportManager());

Having created the factory, the next step is to create a service for our POJO. If our POJO is a service interface, then we need to specify the implementation class. The implementation class must adhere to the javabean contract and have a no-arg constructor.

//note that we'd like to specify our own service name, so we use the overloaded
//create method instead of the simpler one that just takes in a class name
Service service = factory.create(Hello.class, "hi", null, null);
//if Hello.class is an interface, then we need to specify the implementation class
service.setProperty(ObjectInvoker.SERVICE_IMPL_CLASS, HelloImpl.class);

So at this point, we have a factory with a service object. The next step is to register this service and allow external clients to call it. For our example, we'll expose this service in a web application. XFire provides a good base servlet to subclass. The servlet we create will set up xfire, register our service, and expose it. Having done that, it will delegate requests to the xfire controller to process service requests. Putting together the code above with the rest of servlet code, we have:

import org.codehaus.xfire.service.binding.ObjectServiceFactory;
import org.codehaus.xfire.service.binding.ObjectInvoker;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.transport.http.XFireServlet;

public class SOAPServlet extends XFireServlet
{
  public void init() throws ServletException
  {
    super.init();
    ObjectServiceFactory factory = new ObjectServiceFactory(getXFire().getTransportManager(), null);
    //we don't want to expose compareTo
    factory.addIgnoredMethods("java.lang.Comparable");
    Service service = factory.create(Hello.class,"hi", null, null);
    service.setProperty(ObjectInvoker.SERVICE_IMPL_CLASS, HelloImpl.class);
    //we register the service with the controller that handles soap requests
    getController().getServiceRegistry().register(service);
  }
}

Having defined the servlet that handles soap requests, all that remains is to register it in the web application's web.xml:

<servlet>
    <servlet-name>soap</servlet-name>
    <servlet-class>SOAPServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>soap</servlet-name>
    <url-pattern>/soap/*</url-pattern>
  </servlet-mapping>

Once the servlet is deployed, you can verify that the service is correctly processing incoming requests by requesting the WSDL, which can be accessed at /soap/hi?wsdl