+

Search Tips   |   Advanced Search

 

Web Services Resource Framework base faults

 

The Web Services Resource Framework (WSRF) provides a recommended basic fault message element type from which you can derive all service-specific faults. The advantage of a common basic type is that all faults can, by default, contain common information. This behavior is useful in complex systems where faults might be systematically logged, or forwarded through several layers of software before being analyzed. The common information includes the following items:

The following two standard faults are defined for use with every WSRF operation:

ResourceUnkownFault

This fault is used to indicate that the WS-Resource is not known by the service that receives the message.

ResourceUnavailableFault

This fault is used to indicate that the Web service is active, but temporarily unable to provide access to the resource.
The following XML fragment shows an example of a base fault element:

 <wsrf-bf:BaseFault>
    <wsrf-bf:Timestamp>2005-05-31T12:00:00.000Z</wsrf-bf:Timestamp>
    <wsrf-bf:Originator>
      <wsa:Address>
        http://www.example.org/Printer
      </wsa:Address>
      <wsa:ReferenceParameters>
        <pr:pr-id>P1</pr:pr-id>
      </wsa:ReferenceParameters>
    </wsrf-bf:Originator>
    <wsrf-bf:Description>Offline for service maintenance</wsrf-bf:Description>
    <wsrf-bf:FaultCause>OFFLINE</wsrf-bf:FaultCause>
 </wsrf-bf:BaseFault>

 

The BaseFault class

WebSphere Application Server provides Java code mappings for all the base fault element types that are defined by the WSRF specifications, forming an exception hierarchy where each Java exception extends the com.ibm.websphere.wsrf.BaseFault class. Each fault class follows a similar pattern. For example, the BaseFault class defines the following two constructors:

package com.ibm.websphere.wsrf;  public class BaseFault extends Exception
{
    public BaseFault()
    {
       ...
    }
    public BaseFault(EndpointReference originator,
                     ErrorCode errorCode,
                     FaultDescription[] descriptions,
                     IOSerializableSOAPElement faultCause,
                     IOSerializableSOAPElement[] extensibilityElements,
                     Attribute[] attributes)
    {
       ...
    }
    ...
}

 

The IOSerializableSOAPElement class

Because the BaseFault class extends the java.lang.Exception class, the BaseFault class must implement the java.io.Serializable interface. To meet this requirement, all properties of a BaseFault instance must be serializable. Because the javax.xml.soap.SOAPElement class is not serializable, WAS provides an IOSerializableSOAPElement class, which you can use to wrap a javax.xml.soap.SOAPElement instance to provide a serializable form of that instance. Create an IOSerializableSOAPElement instance by using the IOSerializableSOAPElementFactory class, as follows:

// Get an instance of the IOSerializableSOAPElementFactory class
IOSerializableSOAPElementFactory factory = IOSerializableSOAPElementFactory.newInstance();

// Create an IOSerializableSOAPElement from a javax.xml.soap.SOAPElement
IOSerializableSOAPElement serializableSOAPElement = factory.createElement(soapElement);

// You can retrieve the wrapped SOAPElement from the IOSerializableSOAPElement
SOAPElement soapElement = serializableSOAPElement.getSOAPElement();

Any application-specific BaseFault instances must also adhere to this serializable requirement.

 

Application-specific faults

Applications can define their own extensions to the BaseFault element. Use XML type extensions to define a new XML type for the application fault that extends the BaseFaultType element. For example, the following XML fragment creates a new PrinterFaultType element:

 <xsd:complexType name="PrinterFaultType">
   <xsd:complexContent>
     <xsd:extension base="wsrf-bf:BaseFaultType"/>
   </xsd:complexContent>
 </xsd:complexType>

The following example shows how a Web service application, whose WSDL definition might define a print operation that declares two wsdl:fault messages, constructs a PrinterFault object:

import com.ibm.websphere.wsrf.BaseFault; import com.ibm.websphere.wsrf.*; import javax.xml.soap.SOAPFactory;
...
    public void print(PrintRequest req) throws PrinterFault, ResourceUnknownFault
    {
        // Determine the identity of the target printer instance.
        PrinterState state = PrinterState.getState ();
        if (state.OFFLINE)
        {       
            try
            {      
                // Get an instance of the SOAPFactory
                SOAPFactory soapFactory = SOAPFactory.newInstance();
      
                // Create the fault cause SOAPElement
                SOAPElement faultCause = soapFactory.createElement("FaultCause");
                faultCase.addTextNode("OFFLINE");

                // Get an instance of the IOSerializableSOAPElementFactory
                IOSerializableSOAPElementFactory factory = IOSerializableSOAPElementFactory.newInstance();

                // Create an IOSerializableSOAPElement from the faultCause SOAPElement
                IOSerializableSOAPElement serializableFaultCause = factory.createElement(faultCause);

                FaultDescription[] faultDescription = new FaultDescription[1];
                faultDescription[0] = new FaultDescription("Offline for service maintenance");
                throw new PrinterFault(
                         state.getPrinterEndpointReference(),
                         null,
                         faultDescription,
                         serializableFaultCause,
                         null,
                         null);
            }
            catch (SOAPException e)
            {
               ...
            }
        }
        ...

The following code shows how base fault hierarchies are handled as Java exception hierarchies:

import com.ibm.websphere.wsrf.BaseFault; import com.ibm.websphere.wsrf.*;
... try
{
   printer1.print(job1);
} catch (ResourceUnknownFault exc)
{
   System.out.println("Operation threw the ResourceUnknownFault”); 
} catch (PrinterFault exc)
{
   System.out.println("Operation threw PrinterFault”); 
} catch (BaseFault exc)
{
   System.out.println("Exception is another BaseFault”); 
} catch (Exception exc)
{
   System.out.println("Exception is not a BaseFault”); 
}

 

Custom binders

When you define a new application-level base fault, for example the PrinterFault fault with the PrinterFaultType type shown previously, provide a custom binder to define how the Web services run time serializes the Java class into an appropriate XML message, and conversely how to deserialize an XML message into an instance of the Java class. The custom binder must implement the com.ibm.wsspi.webservices.binding.CustomBinder interface. Package the binder in a Java archive (JAR) file along with a declarative metadata file, CustomBindingProvider.xml, in the /META-INF/services directory of the JAR file. This metadata file defines the relationship between the custom binder, the Java BaseFault implementation and the BaseFault type. For example, you might define a custom binder called PrinterFaultTypeBinder, to map between the XML PrinterFaultType element and its Java implementation, PrinterFault, as follows:

<customdatabinding:provider
   xmlns:customdatabinding="http://www.ibm.com/webservices/customdatabinding/2004/06"
   xmlns:pr="http://example.org/printer.xsd"
   xmlns="http://www.ibm.com/webservices/customdatabinding/2004/06">
 <mapping>
  <xmlQName>pr:PrinterFaultType</xmlQName>
  <javaName>PrinterFault</javaName>
  <qnameScope>complexType</qnameScope>
  <binder>PrinterFaultTypeBinder</binder>
 </mapping>
</customdatabinding:provider>

 

The BaseFaultBinderHelper class

WebSphere Application Server provides a BaseFaultBinderHelper class, which provides support for serializing and deserializing the data that is specific to a root BaseFault class, which all specialized BaseFault classes must extend. If a custom binder uses the BaseFaultBinderHelper class, the custom binder then needs to provide only the additional logic for serializing and deserializing the extended BaseFault data. The following code shows how you can implement a custom binder for the PrinterFaultType element to take advantage of the BaseFaultBinderHelper class support:

import com.ibm.wsspi.wsrf.BaseFaultBinderHelper; import com.ibm.wsspi.wsrf.BaseFaultBinderHelperFactory; import com.ibm.wsspi.webservices.binding.CustomBinder; import com.ibm.wsspi.webservices.binding.CustomBindingContext;
...
  public PrinterFaultTypeBinder implements CustomBinder {
   // Get an instance of the BaseFaultBinderHelper
   private BaseFaultBinderHelper baseFaultBinderHelper = BaseFaultBinderHelperFactory.getBaseFaultBinderHelper();
 
   public SOAPElement serialize(Object data, SOAPElement rootNode, CustomBindingContext context) throws SOAPException
   {
     // Serialize the BaseFault specific data
     baseFaultBinderHelper.serialize(rootNode, (BaseFault)data);
 
     // Serialize any PrinterFault specific data 
     ...
 
     // Return the serialized PrinterFault
     return rootNode;   }
 
   public Object deserialize(SOAPElement rootNode, CustomBindingContext context) throws SOAPException
   {
     // Create an instance of a PrinterFault
     PrinterFault printerFault = new PrinterFault();
 
     // Deserialize the BaseFault specific data - any additional data which 
     // forms the PrinterFault extension will be returned as a SOAPElement[].
     SOAPElement[] printerFaultElements = baseFaultBinderHelper.deserialize(printerFault, rootNode);
 
     // Deserialize the PrinterFault specific data contained within the printerFaultElements SOAPElement[]
     ...
 
     // Return the deserialized PrinterFault
     return printerFault;   }
 
  ...
 
}




 

Related concepts


Web Services Resource Framework support

 

Related tasks


Creating stateful Web services using the Web Services Resource Framework

 

Related information

OASIS WSRF primer