Errores básicos de WSRF (Web Services Resource Framework)
WSRF (Web Services Resource Framework) proporciona un tipo de mensaje de error básico recomendado a partir del cual se pueden derivar todos los errores específicos de servicios. La ventaja de un tipo básico común es que, por omisión, todos los errores contienen información común. Este comportamiento resulta útil en los sistemas complejos donde los errores pueden registrarse cronológicamente de forma sistemática o enviarse a través de varias capas de software antes de que se analicen.
- Una indicación de la hora obligatoria.
- Un elemento que pueda utilizarse para indicar el originador del error.
- Otros elementos que pueden describir y clasificar el error.
- ResourceUnkownFault
- Este error se utiliza para indicar que el servicio que recibe el mensaje no conoce el WS-Resource.
- ResourceUnavailableFault
- Este error se utiliza para indicar que el servicio web está activo, pero que temporalmente no puede proporcionar acceso al recurso.
<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>
Clase BaseFault
Para las aplicaciones JAX-RPC, WebSphere Application Server proporciona correlaciones de código Java™ para todos los tipos de elementos de error básicos definidos por las especificaciones WSRF, que crean una jerarquía de excepciones donde cada excepción Java amplía la clase com.ibm.websphere.wsrf.BaseFault. Todas las clases de error siguen un patrón parecido.
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)
{
...
}
...
}
Clase IOSerializableSOAPElement
Como la clase BaseFault amplía la clase java.lang.Exception, la clase BaseFault debe implementar la interfaz java.io.Serializable. Para cumplir con este requisito, todas las propiedades de una instancia de BaseFault deben ser serializables. Como la clase javax.xml.soap.SOAPElement no es serializable, WebSphere Application Server proporciona una clase IOSerializableSOAPElement, que puede utilizar para envolver una instancia javax.xml.soap.SOAPElement para proporcionar un formato serializable de esa instancia.
// Obtener una instancia de la clase IOSerializableSOAPElementFactory
IOSerializableSOAPElementFactory factory = IOSerializableSOAPElementFactory.newInstance();
// Crear un IOSerializableSOAPElement a partir de un javax.xml.soap.SOAPElement
IOSerializableSOAPElement serializableSOAPElement = factory.createElement(soapElement);
// Puede recuperar el SOAPElement envuelto del IOSerializableSOAPElement
SOAPElement soapElement = serializableSOAPElement.getSOAPElement();
Cualquier instancia BaseFault específica de la aplicación debe cumplir este requisito serializable.
Errores específicos de las aplicaciones
<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
{
// Determinar la identidad de la instancia de impresora de destino.
PrinterState state = PrinterState.getState ();
if (state.OFFLINE)
{
try
{
// Obtener una instancia de la SOAPFactory
SOAPFactory soapFactory = SOAPFactory.newInstance();
// Crear el SOAPElement faultCause
SOAPElement faultCause = soapFactory.createElement("FaultCause");
faultCase.addTextNode("OFFLINE");
// Obtener una instancia de la IOSerializableSOAPElementFactory
IOSerializableSOAPElementFactory factory = IOSerializableSOAPElementFactory.newInstance();
// Crear un IOSerializableSOAPElement a partir del SOAPElement faultCause
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");
}
Enlazadores personalizados
Cuando se define un nuevo error básico de nivel de aplicación, por ejemplo, el error PrinterFault del tipo PrinterFaultType mostrado anteriormente, debe proporcionar un enlazador personalizado para definir cómo durante la ejecución los servicios web serializan la clase Java en el mensaje XML adecuado y, a la inversa, cómo deserializa un mensaje XML en una instancia de la clase 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>
Clase BaseFaultBinderHelper
WebSphere Application Server proporciona una clase BaseFaultBinderHelper, que proporciona soporte para la serialización y deserialización de los datos que son específicos de una clase BaseFault de raíz, que deben ampliar todas las clases BaseFault especializadas. Si un enlazador personalizado utiliza la clase BaseFaultBinderHelper, el enlazador personalizado sólo debe proporcional la lógica adicional para serializar y deserializar los datos de BaseFault ampliados.
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
{
// Obtener una instancia de BaseFaultBinderHelper
private BaseFaultBinderHelper baseFaultBinderHelper = BaseFaultBinderHelperFactory.getBaseFaultBinderHelper();
public SOAPElement serialize(Object data, SOAPElement rootNode, CustomBindingContext context) throws SOAPException
{
// Serializar los datos específicos de BaseFault
baseFaultBinderHelper.serialize(rootNode, (BaseFault)data);
// Serializar cualquier dato específico de PrinterFault
...
// Devolver el PrinterFault serializado
return rootNode;
}
public Object deserialize(SOAPElement rootNode, CustomBindingContext context) throws SOAPException
{
// Crear una instancia de un PrinterFault
PrinterFault printerFault = new PrinterFault();
// Deserializar los datos específicos de BaseFault - los datos adicionales que
// forme parte de la extensión PrinterFault se devolverá como SOAPElement[].
SOAPElement[] printerFaultElements = baseFaultBinderHelper.deserialize(printerFault, rootNode);
// Deserializar los datos específicos de PrinterFault contenidos en SOAPElement[] printerFaultElements
...
// Devolver el PrinterFault deseralizado
return printerFault;
}
...
}