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)キーワードを使用します。
メッセージ・ハンドラー構成
...
| Code Block |
|---|
<?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> |
...
メッセージ・ハンドラー・クラスの例
| Code Block |
|---|
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 ; |
...
...
}
|
...
} |
...