Erreurs de base de Web Services Resource Framework
Web Services Resource Framework (WSRF) fournit un type d'élément de message d'erreur de base recommandé à partir duquel vous pouvez accéder à toutes les erreurs spécifiques au service. L'avantage d'un type de base commun est que toutes les erreurs peuvent, par défaut, contenir des informations communes. Ce comportement est utile dans les systèmes complexes dans lesquels les erreurs peuvent systématiquement être consignées, ou transmises via plusieurs couches logicielles avant d'être analysées.
- Un horodatage obligatoire
- Un élément qui peut être utilisé pour indiquer l'émetteur de l'erreur
- D'autres éléments qui peuvent décrire et classifier l'erreur
- ResourceUnkownFault
- Cette erreur est utilisée pour indiquer que la WS-Resource est inconnue du service qui reçoit le message.
- ResourceUnavailableFault
- Cette erreur est utilisée pour indiquer que le service Web est actif, mais temporairement incapable de fournir l'accès à la ressource.
<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>
La classe BaseFault
Pour les applications JAX-RPC, WebSphere Application Server fournit des mappages de code Java™ pour tous les types d'élément d'erreur de base définis par les spécifications WSRF, formant une hiérarchie d'exceptions dans laquelle chaque exception Java étend la classe com.ibm.websphere.wsrf.BaseFault. Chaque classe d'erreurs est basée sur un modèle semblable.
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)
{
...
}
...
}
La classe IOSerializableSOAPElement
Etant donné que la classe BaseFault étend la classe java.lang.Exception, la classe BaseFault doit implémenter l'interface java.io.Serializable. Pour satisfaire cette condition, toutes les propriétés d'une instance BaseFault doivent être sérialisables. Etant donné que la classe javax.xml.soap.SOAPElement n'est pas sérialisable, WebSphere Application Server fournit une classe IOSerializableSOAPElement, que vous pouvez utiliser pour encapsuler une instance javax.xml.soap.SOAPElement et fournir un format sérialisable de cette instance.
// 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();
Les instances BaseFault propres à l'application doivent également satisfaire cette condition sérialisable.
Erreurs propres à l'application
<xsd:complexType name="PrinterFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
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)
{
...
}
}
...
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");
}
Lieurs personnalisés
Lorsque vous définissez une nouvelle erreur de base de niveau application (par exemple, l'erreur PrinterFault de type PrinterFaultType présentée ci-dessus), vous devez fournir un lieur personnalisé pour définir comment le programme d'exécution des services Web sérialise la classe Java en un message XML approprié et, inversement, comment désérialiser un message XML en une instance de classe Java.
<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>
La classe BaseFaultBinderHelper
WebSphere Application Server fournit une classe BaseFaultBinderHelper, qui prend en charge la sérialisation et la désérialisation des données spécifiques à une classe BaseFault racine, que toutes les classes BaseFault spécialisées doivent étendre. Si un lieur personnalisé utilise la classe BaseFaultBinderHelper, le lieur personnalisé ne doit alors fournir que la logique supplémentaire pour la sérialisation et la désérialisation des données BaseFault étendues.
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;
}
...
}