Page History
SOAP Agentメッセージ・ハンドラー・フレームワークはAxisメッセージ・ハンドラー・フレームワークの制限をなくすために開発されたもので、要求ハンドラーや応答ハンドラーを追加する場合にお勧めの方法です。
Apache Axisメッセージ・ハンドラー・フレームワーク用に開発されたメッセージ・ハンドラーは、SOAP Agentメッセージ・ハンドラー・フレームワークで使用できます。
特定のSOAP
...
SOAP Agentメッセージ・ハンドラー・フレームワークはAxisメッセージ・ハンドラー・フレームワークの制限をなくすために開発されたもので、要求ハンドラーや応答ハンドラーを追加する場合にお勧めの方法です。
Apache Axisメッセージ・ハンドラー・フレームワーク用に開発されたメッセージ・ハンドラーは、SOAP Agentメッセージ・ハンドラー・フレームワークで使用できます。
特定のSOAP Agentサービスにメッセージ・ハンドラーを追加するには、SOAPAgentService.propertiesファイルに'service.handlers.サービス名' エントリーを追加します。Wiki Markup
SOAP AgentコマンドOPEN SERVICE (サービス名)が実行されると、実行するプログラムにサービス・クラスとメッセージ・ハンドラー・ファイルが割り当てられます。
service.test=com.acme.service.soap.TestService
...
service.handlers.test=handlers/soapagent-handlers.xml
複数のエージェント・サービス構成を1つのファイルに含めることができます。
要求ハンドラーや応答ハンドラーの追加はオプションです。
複数のハンドラー要素を含めることで簡単なメッセージ・ハンドラー・チェーンを作成できます。
要求メッセージ・ハンドラーと応答メッセージ・ハンドラーは、すべてのサービス操作または1つの特定の操作に割り当てることができます。
各ハンドラー要素はゼロ個以上のパラメータ要素で構成できます。
これらのパラメータ要素がインスタンス化され、インスタンス化されたハンドラー・クラスに渡されます。
パラメータ値の属性に中括弧で囲まれた値がある場合、その値はLANSAフィールド名と仮定され、LANSAフィールドの値がハンドラーに渡されます。LANSAフィールドをハンドラー・クラスで使用できるようにするには、CALLコマンドでSERVICE_EXCHANGE(*FIELD)キーワードを使用します。
メッセージ・ハンドラー構成
...
<?xml |
...
version="1.0" |
...
encoding="utf-8"?> |
...
|
...
<services> |
...
|
...
<!-- |
...
Assign |
...
SOAPHeaderHandler |
...
to |
...
all |
...
operations |
...
in |
...
the |
...
Test |
...
service |
...
--> |
...
<service |
...
name="test"> |
...
|
...
|
...
<request> <handler class="com.acme.axis.handler.SOAPHeaderHandler"/> |
...
|
...
</request> |
...
|
...
|
...
<response> <handler class="com.acme.axis.handler.SOAPHeaderHandler"/> |
...
|
...
</response> |
...
|
...
</service> |
...
|
...
<!-- |
...
Assign |
...
SecurityHandler |
...
and |
...
SOAPHeaderHandler |
...
to |
...
the |
...
Test |
...
service |
...
login |
...
operation |
...
--> |
...
<service |
...
name="test" |
...
operation="login"> |
...
|
...
|
...
<request> <handler class="com.acme.axis.handler.SecurityHandler"> |
...
<parameter name="user" |
...
value=" |
...
{USER |
...
}"/> |
...
<parameter name="acme.keyword" |
...
value="ABC"/> |
...
</handler> |
...
<handler class="com.acme.axis.handler.SOAPHeaderHandler"/> |
...
|
...
</request> |
...
|
...
</service> |
...
|
...
</services> |
...
...
メッセージ・ハンドラー・クラスの例
...
package |
...
com.acme.axis.handler |
...
; |
...
|
...
import |
...
java.io.* |
...
; |
...
|
...
import |
...
java.util.Vector |
...
; |
...
|
...
import |
...
org.apache.axis.Message |
...
; |
...
import |
...
org.apache.axis.SOAPPart |
...
; |
...
import |
...
org.apache.axis.AxisFault |
...
; |
...
import |
...
org.apache.axis.MessageContext |
...
; |
...
|
...
import |
...
org.apache.axis.utils.XMLUtils |
...
; |
...
|
...
import |
...
org.apache.axis.message.SOAPBody |
...
; |
...
import |
...
org.apache.axis.message.SOAPHeader |
...
; |
...
import |
...
org.apache.axis.message.SOAPEnvelope |
...
; |
...
import |
...
org.apache.axis.message.SOAPBodyElement |
...
; |
...
import |
...
org.apache.axis.message.SOAPHeaderElement |
...
; |
...
import |
...
org.apache.axis.message.MessageElement |
...
; |
...
|
...
import |
...
org.apache.axis.message.RPCParam |
...
; |
...
import |
...
org.apache.axis.message.RPCElement |
...
; |
...
import |
...
org.apache.axis.message.PrefixedQName |
...
; |
...
|
...
import |
...
org.apache.axis.description.ParameterDesc |
...
; |
...
|
...
import |
...
org.apache.axis.encoding.SerializationContext |
...
; |
...
|
...
import |
...
org.w3c.dom.Node |
...
; |
...
import |
...
org.w3c.dom.Element |
...
; |
...
import |
...
org.w3c.dom.Document |
...
; |
...
import |
...
org.w3c.dom.NodeList |
...
; |
...
|
...
import |
...
org.w3c.dom.ls.LSOutput |
...
; |
...
import |
...
org.w3c.dom.ls.LSSerializer |
...
; |
...
import |
...
org.w3c.dom.ls.DOMImplementationLS |
...
; |
...
|
...
import |
...
org.w3c.dom.bootstrap.DOMImplementationRegistry |
...
; |
...
|
...
import |
...
com.lansa.jsm.JSMTrace |
...
; |
...
import |
...
com.lansa.jsm.JSMCommand |
...
; |
...
import |
...
com.lansa.jsm.JSMResource |
...
; |
...
|
...
import |
...
com.lansa.jsm.service.ServiceHelper |
...
; |
...
|
...
public |
...
class |
...
MyHandler |
...
extends |
...
org.apache.axis.handlers.BasicHandler |
...
{ private final static String EMPTY_STRING |
...
= |
...
"" |
...
; |
...
|
...
private |
...
final |
...
static |
...
String |
...
ENCODING_UTF8 |
...
= |
...
"UTF-8" |
...
; |
...
|
...
private |
...
final |
...
static |
...
String |
...
[ |
...
] |
...
FORM_NAMES |
...
= |
...
{ |
...
"", |
...
"FORM_STRING", |
...
"FORM_INPUTSTREAM", |
...
"FORM_SOAPENVELOPE", |
...
"FORM_BYTES", |
...
"FORM_BODYINSTREAM", |
...
"FORM_FAULT", |
...
"FORM_OPTIMIZED" |
...
} |
...
; |
...
|
...
private |
...
JSMTrace |
...
m_trace |
...
= |
...
null |
...
; |
...
|
...
private |
...
JSMResource |
...
m_serviceResource |
...
= |
...
null |
...
; |
...
|
...
public |
...
void |
...
init |
...
() |
...
{ /* オプション - これは BasicHandler の init スタブをオーバーライド 最初に、init がすべてのハンドラーに対して呼び出される 次に、invoke がすべてのハンドラーに対して呼び出される 最後に、cleanup がすべてのハンドラーに対して呼び出される 以下を使用してハンドラー間で情報を渡すことが可能 MessageContext - setProperty ( 文字列名, オブジェクト値 ) MessageContext - Object value getProperty ( 文字列名 ) */ } public void invoke ( org.apache.axis.MessageContext |
...
messageContext |
...
) |
...
throws |
...
AxisFault { try { m_trace = (JSMTrace)getOption |
...
( |
...
"jsm.handler.property.trace" |
...
) |
...
; m_serviceResource |
...
= |
...
(JSMResource)getOption |
...
( |
...
"jsm.handler.property.resource" |
...
) |
...
; traceOptions () ; modifyMessage ( messageContext ) ; } catch ( Exception e ) { throw new AxisFault ( "MyHandler: exception : " + e.toString () ) ; } } public void cleanup () { /* オプション - これは BasicHandler の cleanup スタブをオーバーライド */ if ( m_trace != null ) { m_trace.println ( "MyHandler: cleanup" ) ; } } private final void traceOptions () { /* 以下はハンドラー・パラメータからのプロパティ */ String value = (String)getOption ( "acme.keyword" ) ; /* 以下のプロパティは JSM サービスが提供 */ String type = (String)getOption ( "jsm.handler.property.type" |
...
) |
...
; |
...
String service = (String)getOption |
...
( |
...
"jsm.handler.property.service" |
...
) |
...
; |
...
String operation = (String)getOption |
...
( |
...
"jsm.handler.property.operation" |
...
) |
...
; /* コマンド呼び出し */ JSMCommand command = (JSMCommand)getOption |
...
( |
...
"jsm.handler.property.command" |
...
) |
...
; if ( m_trace |
...
!= |
...
null |
...
) { m_trace.println |
...
( |
...
"MyHandler: |
...
invoke" |
...
) |
...
; m_trace.println |
...
( |
...
"MyHandler: |
...
acme.keyword |
...
: |
...
" |
...
+ |
...
value |
...
) |
...
; m_trace.println |
...
( |
...
"MyHandler: |
...
jsm.handler.property.type |
...
: |
...
" |
...
+ |
...
type |
...
) |
...
; m_trace.println |
...
( |
...
"MyHandler: |
...
jsm.handler.property.service |
...
: |
...
" |
...
+ |
...
service |
...
) |
...
; |
...
m_trace.println |
...
( |
...
"MyHandler: |
...
jsm.handler.property.operation |
...
: |
...
" |
...
+ |
...
operation |
...
) |
...
; m_trace.println |
...
( |
...
"MyHandler: |
...
jsm.handler.property.command |
...
: |
...
" |
...
+ |
...
command.toString |
...
() |
...
) |
...
; } } private final void modifyMessage ( org.apache.axis.MessageContext |
...
messageContext |
...
) |
...
throws |
...
Exception { Message message = messageContext.getCurrentMessage |
...
() |
...
; |
...
if ( message == null ) { throw new IllegalArgumentException ( "no message available" ) ; } /* トレース・メッセージ - 出力は内部フォームにより異なる */ // traceMessage ( message ) ; /* SOAP 部分 */ SOAPPart soapPart = (SOAPPart)message.getSOAPPart |
...
() |
...
; |
...
int form = soapPart.getCurrentForm |
...
() |
...
; |
...
if ( m_trace |
...
!= |
...
null |
...
) { m_trace.println |
...
( |
...
"MyHandler: |
...
current |
...
message |
...
form |
...
: |
...
", |
...
FORM_NAMES |
...
[form |
...
] |
...
) |
...
; } /* SOAP エンベロープ - 内部フォームを SOAPEnvelope に変換 */ SOAPEnvelope envelope = soapPart.getAsSOAPEnvelope () ; // traceEnvelope ( envelope ) ; /* 要求または応答の処理 */ if ( isRequest () ) { modifyHeader ( envelope ) ; traceBody ( envelope ) ; // setRequestMessage1 ( soapPart ) ;// setRequestMessage2 ( messageContext ) ; setRequestMessage3 ( messageContext, envelope ) ; return ; } if ( isResponse () ) { setResponseMessage1 ( messageContext ) ; return ; } } private final void modifyHeader ( SOAPEnvelope envelope ) throws Exception { Vector vector = envelope.getHeaders () ; int count = vector.size () ; if ( m_trace != null ) { m_trace.println ( "MyHandler: header count : " + count ) ; } for ( int i=0; i < count; i++ ) { SOAPHeaderElement element = (SOAPHeaderElement)vector.elementAt ( i ) ; if ( m_trace != null ) { m_trace.println ( "MyHandler: soap header : " + element.getElementName () ) ; } } if ( m_trace != null ) { m_trace.println ( "MyHandler: add header" ) ; } envelope.addHeader ( createHeader () ) ; } private final SOAPHeaderElement createHeader () throws Exception { SOAPHeaderElement elementHead = new org.apache.axis.message.SOAPHeaderElement |
...
( |
...
"namespace", |
...
"AuthHeader" |
...
) |
...
; |
...
MessageElement elementSession = (MessageElement)elementHead.addChildElement |
...
( |
...
"SessionId" |
...
) |
...
; elementSession.addTextNode |
...
( |
...
"text" |
...
) |
...
; elementHead.setActor |
...
( |
...
null |
...
) |
...
; return elementHead ; } private final boolean isRequest () { String type = (String)getOption ( "jsm.handler.property.type" |
...
) |
...
; |
...
if ( type.equals |
...
( |
...
"request" |
...
) |
...
) { return true ; } return false ; } private final boolean isResponse () { String type = (String)getOption ( "jsm.handler.property.type" |
...
) |
...
; |
...
if ( type.equals |
...
( |
...
"response" |
...
) |
...
) { return true ; } return false ; } private final void setRequestMessage1 ( SOAPPart soapPart ) throws Exception { /* 以下が最後のメッセージ変更 Message.writeTo -> SOAPPart.writeTo メソッドはバイトをそのまま送信 この方法では、byte[] コンテンツでフォーム変換が発生するリスク有り */ if ( m_trace != null ) { m_trace.println ( "Set request message 1 using byte[]" ) ; } byte[] message = "any content sent as bytes".getBytes ( ENCODING_UTF8 ) ; soapPart.setCurrentMessage ( message, SOAPPart.FORM_BYTES ) ; } private final void setRequestMessage2 ( MessageContext messageContext ) throws Exception { /* この例では、ファイルからバイト コンテンツを使用 ただし、ドキュメントを byte[] メモリー内にシリアライズ、 もしくは、文字列を作成し、コンテンツの引数として使用なども可能。 */ if ( m_trace != null ) { m_trace.println ( "Set request message 2 using byte[] message" ) ; } File file = new File ( "ENVELOPE_REQUEST.XML" ) ; if ( m_trace != null ) { m_trace.println ( "MyHandler: set resquest message from external file : " + file.getName () ) ; } // String content = "<?xml ...." ; byte[] content = readFile ( file ) ; Message requestMessage = new Message ( content ) ; messageContext.setRequestMessage ( requestMessage ) ; } private final void setRequestMessage3 ( MessageContext messageContext, SOAPEnvelope envelope ) throws Exception { if ( m_trace != null ) { m_trace.println ( "Set request message 3 using document" ) ; } Document document = envelope.getAsDocument () ; /* ドキュメントの変更 */ byte[] content = serializeDocument ( document ) ; Message requestMessage = new Message ( content ) ; messageContext.setRequestMessage ( requestMessage ) ; } private final void setResponseMessage1 ( MessageContext messageContext ) throws Exception { /* この例では、ファイルからバイト コンテンツを使用 ただし、ドキュメントを byte[] メモリー内にシリアライズ、 もしくは、文字列を作成し、コンテンツの引数として使用なども可能。 */ File file = new File ( "ENVELOPE_RESPONSE.XML" ) ; if ( m_trace != null ) { m_trace.println ( "MyHandler: set response message from external file : " + file.getName () ) ; } byte[] content = readFile ( file ) ; Message responseMessage = new Message ( content ) ; messageContext.setResponseMessage ( responseMessage ) ; } private final byte[] serializeDocument ( Document document ) throws Exception { DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance () ; DOMImplementationLS implementation = (DOMImplementationLS)registry.getDOMImplementation ( "LS" ) ; LSOutput output = implementation.createLSOutput () ; LSSerializer serializer = implementation.createLSSerializer () ; ByteArrayOutputStream outputStream = new ByteArrayOutputStream ( 4096 ) ; output.setEncoding ( "utf-8" ) ; output.setByteStream ( outputStream ) ; serializer.setNewLine ( "\n" ) ; serializer.write ( document, output ) ; return outputStream.toByteArray () ; } private final void traceMessage ( Message message ) { if ( m_trace == null ) { return ; } try { String fileName = "MYHANDLER_MESSAGE" + ServiceHelper.getSequenceLabel ( m_trace ) + ".XML" ; FileOutputStream outputStream = new FileOutputStream ( m_trace.createTraceFile ( fileName ) ) ; message.writeTo ( outputStream ) ; outputStream.close () ; } catch ( Throwable t ) { m_trace.print ( t ) ; } } private final void traceEnvelope ( SOAPEnvelope envelope ) { if ( m_trace == null ) { return ; } /* ここでは次の MessageElement を使用 - getAsDocument - getAsDocument - getAsString エレメントを文字列に、パーサーをドキュメントに変換 */ try { Document document = envelope.getAsDocument () ; DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance () ; DOMImplementationLS implementation = (DOMImplementationLS)registry.getDOMImplementation ( "LS" ) ; LSOutput output = implementation.createLSOutput () ; LSSerializer serializer = implementation.createLSSerializer () ; String fileName = "MYHANDLER_ENVELOPE" + ServiceHelper.getSequenceLabel ( m_trace ) + ".XML" ; FileOutputStream outputStream = new FileOutputStream ( m_trace.createTraceFile ( fileName ) ) ; output.setEncoding ( "utf-8" ) ; output.setByteStream ( outputStream ) ; serializer.setNewLine ( "\n" ) ; serializer.write ( document, output ) ; outputStream.close () ; } catch ( Throwable t ) { m_trace.print ( t ) ; } } private final void traceBody ( SOAPEnvelope envelope ) throws Exception { if ( m_trace == null ) { return ; } SOAPBody body = (SOAPBody)envelope.getBody () ; if ( body == null ) { throw new IllegalArgumentException ( "no body available" ) ; } RPCElement operation = getOperation ( body ) ; if ( operation == null ) { throw new IllegalArgumentException ( "no operation available" ) ; } m_trace.println ( "MyHandler: operation name : " + operation.getElementName () ) ; traceParameters ( operation ) ; } private final void traceParameters ( RPCElement operation ) throws Exception { if ( m_trace == null ) { return ; } Vector vector = operation.getParams () ; int count = vector.size () ; m_trace.println ( "MyHandler: parameter count : " + count ) ; for ( int i=0; i < count; i++ ) { RPCParam parameter = (RPCParam)vector.get ( i ) ; ParameterDesc parameterDesc = parameter.getParamDesc () ; Class klazz = parameterDesc.getJavaType () ; m_trace.println ( "MyHandler: parameter name : " + parameter.getElementName () ) ; if ( klazz.isArray () ) { m_trace.println ( "MyHandler: parameter type : array of " + klazz.getComponentType().getName () ) ; } else { m_trace.println ( "MyHandler: parameter type : " + klazz.getName () ) ; } } } private final RPCElement getOperation ( SOAPBody body ) { NodeList nodeList = body.getChildNodes () ; if ( nodeList == null ) { return null ; } int count = nodeList.getLength () ; if ( count == 0 ) { return null ; } for ( int i=0; i < count; i++ ) { Node node = nodeList.item ( i ) ; if ( node instanceof RPCElement ) { return(RPCElement)node ; } } return null ; } private final MessageElement getChildMessageElement ( MessageElement element ) { NodeList nodeList = element.getChildNodes () ; if ( nodeList == null ) { return null ; } int count = nodeList.getLength () ; if ( count == 0 ) { return null ; } for ( int i=0; i < count; i++ ) { Node node = nodeList.item ( i ) ; if ( node instanceof RPCElement ) { return(MessageElement)node ; } if ( node instanceof SOAPBodyElement ) { return(MessageElement)node ; } if ( node instanceof RPCParam ) { return(MessageElement)node ; } if ( node instanceof MessageElement ) { return(MessageElement)node ; } if ( node instanceof javax.xml.soap.SOAPElement ) { /* インターフェース */ } } return null ; } public final static byte[] readFile ( File file ) throws IOException { int length = (int)file.length () ; byte[] content = new byte[length] ; FileInputStream inputStream = new FileInputStream ( file ) ; inputStream.read ( content ) ; inputStream.close () ; return content ; }} |