Web Services Resource Framework ベースの障害
Web Services Resource Framework (WSRF) は推奨される基本的な障害メッセージ・エレメント・タイプを提供しており、ユーザーはここからサービス固有のすべての障害を引き出すことができます。 共通の基本タイプの利点は、デフォルトで、すべての障害が共通の情報を含むことができることです。 この振る舞いは、障害が整然とログに記録されたり、分析される前にソフトウェアの複数の層を通じて転送される複雑なシステムにおいて有益です。
- 必須のタイム・スタンプ。
- 障害の開始元を示すのに使用できるエレメント。
- 障害を説明し、分類できるその他のエレメント。
- ResourceUnkownFault
- この障害は、WS-Resource がメッセージを受信するサービスによって認識されていないことを示すのに使用します。
- ResourceUnavailableFault
- この障害は、Web サービスはアクティブであるが、リソースへのアクセスを提供できないことを示すのに使用します。
<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>
BaseFault クラス
JAX-RPC アプリケーションの場合、WebSphere® Application Server は WSRF 仕様により定義されたすべての基本障害エレメント・タイプの Java™ コード・マッピングを提供し、各 Java 例外が com.ibm.websphere.wsrf.BaseFault クラスを拡張する、例外階層を形成します。各障害クラスは同じようなパターンに従います。
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)
{
...
}
...
}
IOSerializableSOAPElement クラス
BaseFault クラスは java.lang.Exception クラスを拡張するため、java.io.Serializable インターフェースを実装する必要があります。この要件を満たすには、BaseFault インスタンスのすべてのプロパティーがシリアライズ可能である必要があります。javax.xml.soap.SOAPElement クラスはシリアライズ可能ではないため、WebSphere Application Server は IOSerializableSOAPElement クラスを提供します。このクラスを使用して javax.xml.soap.SOAPElement インスタンスをラップし、そのインスタンスのシリアライズ可能な形式を提供します。
// 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();
すべてのアプリケーション固有の BaseFault インスタンスは、このシリアライズ可能な要件も遵守する必要があります。
アプリケーション固有の障害
<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");
}
カスタム・バインダー
新規のアプリケーション・レベルの基本障害を定義する場合 (例えば上記に示すタイプ PrinterFaultType の PrinterFault)、ユーザーはカスタム・バインダーを提供して、Web サービス・ランタイムが Java クラスを適切な XML メッセージにシリアライズし、反対に XML メッセージを 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>
BaseFaultBinderHelper クラス
WebSphere Application Server は BaseFaultBinderHelper クラスを提供します。このクラスは、すべての特殊な BaseFault クラスが拡張しなければならないルート BaseFault に固有のデータを、シリアライズおよびデシリアライズするためのサポートを提供します。カスタム・バインダーが BaseFaultBinderHelper クラスを使用する場合、カスタム・バインダーは拡張された BaseFault データをシリアライズおよびデシリアライズするための追加ロジックのみを提供する必要があります。
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;
}
...
}