Page History
...
SOAP AgentコマンドOPEN SERVICE (サービス名)が実行されると、実行するプログラムにサービス・クラスとメッセージ・ハンドラー・ファイルが割り当てられます。
service.test=com.acme.service.soap.TestServiceservice.handlers.test=handlers/soapagent-handlers.xml
複数のエージェント・サービス構成を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 ; |
...
} |
...
} |