Web Services Resource Framework (WSRF) は推奨される基本的な障害メッセージ・エレメント・タイプを提供しており、ユーザーはここからサービス固有のすべての障害を引き出すことができます。 共通の基本タイプの利点は、デフォルトで、すべての障害が共通の情報を含むことができることです。 この振る舞いは、障害が整然とログに記録されたり、分析される前にソフトウェアの複数の層を通じて転送される複雑なシステムにおいて有益です。
<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>
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) { ... } ... }
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>
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 which // 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; } ... }