WSRF-Fehler

Das Web Services Resource Framework (WSRF) stellt einen empfohlenen Basiselementtyp für Fehlernachrichten bereit, aus dem alle servicespezifischen Fehler abgeleitet werden können. Der Vorteil eines einheitlichen Basistyps besteht darin, dass alle Fehler standardmäßig einheitliche Informationen enthalten können. Dies ist in komplexen Systemen nützlich, in denen Fehler systematisch protokolliert oder durch mehrere Softwareschichten hindurch weitergeleitet werden können, bevor sie analysiert werden.

Die einheitlichen Informationen enthalten folgende Angaben:
  • Eine obligatorische Zeitmarke.
  • Ein Element, mit dem der Ersteller des Fehlers angegeben werden kann.
  • Andere Elemente, die den Fehler beschreiben und klassifizieren können.
Die folgenden zwei Standardfehler sind für die Verwendung in jeder WSRF-Operation definiert:
ResourceUnkownFault
Mit diesem Fehler wird angezeigt, dass die WS-Resource dem Service, der die Nachricht empfängt, nicht bekannt ist.
ResourceUnavailableFault
Mit diesem Fehler wird angezeigt, dass der Web-Service zwar aktiv ist, aber derzeit keinen Zugriff auf die Ressource bereitstellen kann.
Das folgende XML-Fragment zeigt ein Beispiel eines Basisfehlerelements:
 <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>
Wichtig: Die Elemente und Klassen, die im restlichen Teil dieses Artikels beschrieben werden, gelten nur für JAX-RPC-Anwendungen. Wenn Ihre Anwendung JAX-WS verwendet, verwenden Sie die beispielsweise vom Tool wsimport generierten Artefakte aus dem WSDL-Dokument und dem XML-Schema der Anwendung, die den speziellen BaseFault-Typ definieren und verwenden.

Die Klasse BaseFault

Für JAX-RPC-Anwendungen stellt WebSphere Application Server für alle durch die WSRF-Spezifikationen definierten Basisfehlerelementtypen Java™-Codezuordnungen bereit, wodurch eine Hierarchie von Ausnahmen entsteht, in der jede Java-Ausnahme die Klasse com.ibm.websphere.wsrf.BaseFault erweitert. Jede Fehlerklasse folgt einem ähnlichen Muster.

Beispielsweise definiert die Klasse BaseFault selbst die folgenden beiden Konstruktoren:
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)
    {
       ...
    }
    ...
}

Die Klasse IOSerializableSOAPElement

Da die Klasse BaseFault die Klasse java.lang.Exception erweitert, muss sie die Schnittstelle "java.io.Serializable" implementieren. Damit diese Voraussetzung erfüllt wird, müssen alle Eigenschaften einer BaseFault-Instanz selbst serialisierbar sein. Da die Klasse "javax.xml.soap.SOAPElement" nicht serialisierbar ist, stellt WebSphere Application Server die Klasse IOSerializableSOAPElement bereit, in die eine Instanz von javax.xml.soap.SOAPElement eingeschlossen werden kann, um eine serialisierbare Form dieser Instanz zu erhalten.

Erstellen Sie eine Instanz von IOSerializableSOAPElement, indem Sie die Klasse IOSerializableSOAPElementFactory wie folgt verwenden:
// Eine Instanz der Klasse IOSerializableSOAPElementFactory abrufen
IOSerializableSOAPElementFactory factory = IOSerializableSOAPElementFactory.newInstance();

// Ein IOSerializableSOAPElement aus einem javax.xml.soap.SOAPElement erstellen
IOSerializableSOAPElement serializableSOAPElement = factory.createElement(soapElement);

// Sie können das eingeschlossene SOAPElement aus dem IOSerializableSOAPElement abrufen
SOAPElement soapElement = serializableSOAPElement.getSOAPElement();

Alle anwendungsspezifischen BaseFault-Instanzen müssen ebenfalls serialisierbar sein.

Anwendungsspezifische Fehler

Anwendungen können eigene Erweiterungen für das Element BaseFault definieren. Verwenden Sie die XML-Typ-Erweiterungen, um einen neuen XML-Typ für den Anwendungsfehler zu definieren, der das Element BaseFaultType erweitert. Das folgenden XML-Fragment erstellt beispielsweise ein neues PrinterFaultType-Element:
 <xsd:complexType name="PrinterFaultType">
   <xsd:complexContent>
     <xsd:extension base="wsrf-bf:BaseFaultType"/>
   </xsd:complexContent>
 </xsd:complexType>
Das folgende Beispiel zeigt, wie eine Web-Service-Anwendung, deren WSDL-Definition eine Druckoperation definieren kann, die zwei Nachrichten vom Typ wsdl:fault deklariert, ein PrinterFault-Objekt erstellt:
import com.ibm.websphere.wsrf.BaseFault;
import com.ibm.websphere.wsrf.*;
import javax.xml.soap.SOAPFactory;
...
    public void print(PrintRequest req) throws PrinterFault, ResourceUnknownFault
    {
        // Die Identität der Zieldruckerinstanz ermitteln.
        PrinterState state = PrinterState.getState ();
        if (state.OFFLINE)
        {       
            try
            {      
                // Eine Instanz der SOAPFactory abrufen
                SOAPFactory soapFactory = SOAPFactory.newInstance();
      
                // Das SOAPElement faultCause erstellen
                SOAPElement faultCause = soapFactory.createElement("FaultCause");
                faultCase.addTextNode("OFFLINE");

                // Eine Instanz der IOSerializableSOAPElementFactory abrufen
                IOSerializableSOAPElementFactory factory = IOSerializableSOAPElementFactory.newInstance();

                // Ein IOSerializableSOAPElement aus dem SOAPElement faultCause erstellen
                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)
            {
               ...
            }
        }
        ...
Der folgende Code zeigt, wie Fehlerhierarchien als Hierarchien von Java-Ausnahmen behandelt werden:
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"); 
}

Angepasste Binder

Wenn Sie einen neuen Basisfehler auf Anwendungsebene definieren, z. B. den oben gezeigten Druckerfehler (PrinterFault) des Typs PrinterFaultType, müssen Sie einen angepassten Binder bereitstellen, der definiert, wie die Web-Service-Laufzeit die Java-Klasse in eine geeignete XML-Nachricht serialisiert und wie umgekehrt eine XML-Nachricht in eine Instanz der Java-Klasse deserialisiert wird.

Der angepasste Binder muss die Schnittstelle "com.ibm.wsspi.webservices.binding.CustomBinder" implementieren. Packen Sie den Binder in eine JAR-Datei (Java Archive) zusammen mit einer deklarativen Metadatendatei, CustomBindingProvider.xml, die sich im Verzeichnis /META-INF/services der JAR-Datei befindet. Diese Metadatendatei definiert die Beziehung zwischen dem angepassten Binder, der Java-BaseFault-Implementierung und dem BaseFault-Typ. Beispielsweise könnten Sie einen angepassten Binder mit dem Namen PrinterFaultTypeBinder definieren, der eine Zuordnung zwischen dem XML-Element PrinterFaultType und seiner Java-Implementierung PrinterFault vornimmt:
<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>

Die Klasse BaseFaultBinderHelper

WebSphere EntApplication Server stellt die Klasse BaseFaultBinderHelper bereit, die Unterstützung für die Serialisierung und Entserialisierung der Daten einer BaseFault-Stammklasse liefert, die von allen spezialisierten BaseFault-Klassen erweitert werden muss. Wenn ein angepasster Binder die Klasse BaseFaultBinderHelper verwendet, dann muss dieser angepasste Binder nur die zusätzliche Logik zum Serialisieren und Deserialisieren der erweiterten BaseFault-Daten bereitstellen.

Der folgende Code zeigt, wie ein angepasster Binder für das Element PrinterFaultType implementiert wird, damit er die Unterstützung durch die Klasse BaseFaultBinderHelper nutzt:
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
{
   // Eine Instanz des BaseFaultBinderHelper abrufen
   private BaseFaultBinderHelper baseFaultBinderHelper = BaseFaultBinderHelperFactory.getBaseFaultBinderHelper();
 
   public SOAPElement serialize(Object data, SOAPElement rootNode, CustomBindingContext context) throws SOAPException
   {
     // Die spezifischen BaseFault-Daten serialisieren
     baseFaultBinderHelper.serialize(rootNode, (BaseFault)data);
 
     // Die spezifischen PrinterFault-Daten serialisieren
     ...
 
     // Den serialisierten PrinterFault zurückgeben
     return rootNode;
   }
 
   public Object deserialize(SOAPElement rootNode, CustomBindingContext context) throws SOAPException
   {
     // Eine Instanz eines PrinterFault erstellen
     PrinterFault printerFault = new PrinterFault();
 
     // Die spezifischen BaseFault-Daten entserialisieren - die zusätzlichen Daten, die
     // die PrinterFault-Erweiterung bilden, werden als SOAPElement[] zurückgegeben.
     SOAPElement[] printerFaultElements = baseFaultBinderHelper.deserialize(printerFault, rootNode);
 
     // Spezifischen PrinterFault-Daten, die im SOAPElement[] printerFaultElements enthalten sind, entserialisieren
     ...
 
     // Den deserialisierten PrinterFault zurückgeben
     return printerFault;
   }
 
  ...
 
}

Symbol, das den Typ des Artikels anzeigt. Konzeptartikel



Symbol für Zeitmarke Letzte Aktualisierung: 25.05.2016
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=cwbs_wsrf_basefault
Dateiname:cwbs_wsrf_basefault.html