+

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 we 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 elements and classes that are discussed in the rest of this topic apply to JAX-RPC applications only. If the application uses JAX-WS, use the artifacts that are generated, for example by the wsimport tool, from the application WSDL document and XML schema that define and use the specific BaseFault type.

 

The BaseFault class

For JAX-RPC applications, WAS provides Java code mappings for all the base fault element types 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 we 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);


// We 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 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, we 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

WAS 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 we 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 that // 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


Create stateful Web services using the Web Services Resource Framework

 

Related


wsimport command for JAX-WS applications

 

Related information

OASIS WSRF primer