apache > ws.apache
WSRF
 

Writing a Service Class

Introduction

The service class is the representation of your WSDL file as a Web service. The public methods in the service class correspond to the SOAP operations exposed by your Web service.

If you use the Wsdl2Java tool, the service class is automatically generated and typically does not need to be modified. However; this section discusses how to write a service class if you choose to do so. Initially, you should model your service off of the included FileSystemService example to ensure that you write a valid service.

What classes will need to be written?

The provided example FileSystem includes a FileSystemService class. The FileSystemService extends AbstractFileSystemService, which contains any code which should not need to be altered. The abstract class mainly consists of the specification operations (i.e. getMultipleResourceProperties), while the service class which extends this class contains the "custom" operations. In the case of FileSystemService, the custom operations are mount and unmount.

We recommend this structure for writing your service class, however you may write the service however you like. Our description will describe the use of the abstract class to separate the functionality.

The AbstractService class

The abstract class is the superclass for your service and will contain most of the specification-specific operations and utility operations. Our description of writing the class will be based on the example.filesystem.AbstractFileSystemService class.

We will describe the class in sections:

  1. Class Declaration
  2. WsrfService Interface
  3. Class Variable
  4. Operations

Class Declaration

When declaring your abstract class, you must implement org.apache.ws.resource.handler.WsrfService. This interface provides methods for initialization, obtaining the ResourceContext and getting the SoapMethodNameMap used for mapping incoming request QName's to method name for a given object. It basically ensures that Apache WSRF can interact with your service class.

The AbstractFileSystemService class declaration is as follows:

						
 abstract class AbstractFileSystemService implements WsrfService,
       GetResourcePropertyPortType,
       GetMultipleResourcePropertiesPortType,
       SetResourcePropertiesPortType,
       QueryResourcePropertiesPortType,
       ImmediateResourceTerminationPortType,
       ScheduledResourceTerminationPortType
					

You should notice that the class implements WsrfService (described above) and various *PortType inerfaces. Each PortType interface is a Java representation of a specification's WSDL portType declaration. By implementing the PortType interface corresponding to the specification-defined portTypes you are interested in, you will ensure you get the correct method signature for the method call.

The packages: org.apache.ws.resource.properties.porttype and org.apache.ws.resource.lifetime.porttype contain the interfaces for the specifications. You should refer to these packages when selecting the operations you'd like to support.

WsrfService Interface

All Apache WSRF services must implement the WsrfService interface. The interface provides operation "hooks" which will allow Apache WSRF to interact with your service. There are currenty three operations defined by the interface:

   /**
    * Returns the SoapMethodNameMap for the Service, to determine
    * which method to invoke for an incoming request.
    *
    * @return SoapMethodNameMap
    */
   public SoapMethodNameMap getMethodNameMap(  );

   /**
    * Returns the ResourceContext for the given Service.
    *
    * @return ResourceContext
    */
   public ResourceContext getResourceContext(  );

   /**
    * Initialization method.
    */
   public void init(  );

The getMethodNameMap() returns a SoapMethodNameMap implementation which contains mappings of WSDL operation QNames to Java method names. If you have custom operations you will need to create an instance of ServiceSoapMethodName and add mappings for your operations.

The getResourceContext() operation returns the ResourceContext associated with this service. This method may be left abstract in this class and later implemented in the Service extension of your abstract class.

The init() method is provided to give you an opportunity to initialize members for your Service (e.g. ServiceSoapMethodName )

Class Variables

The class variables which should be defined are:

  1. TARGET_NSURI - The target namespace of your sevice's WSDL file.
  2. TARGET_NSPREFIX - The target prefix to be associated with your service's namespace.

In the AbstractFileSystem we have:

public static final String TARGET_NSURI = "http://ws.apache.org/resource/example/filesystem";
public static final String TARGET_NSPREFIX = "fs";

Notice the fields are public static final since they are constants that other classes may need to access.

Operations

The operations which are defined in the abstract class should be operations which typically should not need to be touched. The specification-defined operations are a prime example. Upon looking at the AbstractFileSystem class, we see the operations defined for methods like: getMultipleResourceProperties(...). The body of these methods are similar in that they hand the invocation off to a portType implementation class:

public GetResourcePropertyResponseDocument getResourceProperty( GetResourcePropertyDocument requestDoc )
   {
      return new GetResourcePropertyPortTypeImpl( getResourceContext(  ) ).getResourceProperty( requestDoc );
   }

Notice the GetMultipleResourcePropertiesPortTypeImpl class being used. A portType implementation class is used to handle the operations defined in a particular specification-defined portType.

The packages: org.apache.ws.resource.properties.porttype.impl and org.apache.ws.resource.lifetime.porttype.impl contain the portType implementation classes for the portTypes defined by the WS-ResourceProperties and WS-ResourceLifetime specifications. You should refer to these packages when implementing the operations from these specifications.

The Service class

The service class is the extension of the abstract service class we previously outlined. You will need to implement a constructor that takes a ResourceContext as a parameter. This constructor should call the equivalent constructor in the superclass.

The Service class should contain any custom operations that were defined in the most-derived portType for the service. The safest way to handle the parameters and return type of the methods is to simply use XmlObject:

   public XmlObject mount( XmlObject requestDoc )
   {
      try
      {
         return XmlObject.Factory.parse( "<MountResponse />" );
      }
      catch ( XmlException xe )
      {
         throw new JAXRPCException( xe );
      }
   }
        			

XmlBeans will generate strongly-typed objects for the types defined in the schema section of your WSDL document, and these types may be used, however if you are unsure which type will get passed to your operation, you can be sure it will implement the XmlObject interface, since all XmlBeans implement this interface.