Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

SOAP Agentメッセージ・ハンドラー・フレームワークはAxisメッセージ・ハンドラー・フレームワークの制限をなくすために開発されたもので、要求ハンドラーや応答ハンドラーを追加する場合にお勧めの方法です。

Apache Axisメッセージ・ハンドラー・フレームワーク用に開発されたメッセージ・ハンドラーは、SOAP Agentメッセージ・ハンドラー・フレームワークで使用できます。

特定のSOAP

...

Wiki MarkupSOAP Agentメッセージ・ハンドラー・フレームワークはAxisメッセージ・ハンドラー・フレームワークの制限をなくすために開発されたもので、要求ハンドラーや応答ハンドラーを追加する場合にお勧めの方法です。 Apache Axisメッセージ・ハンドラー・フレームワーク用に開発されたメッセージ・ハンドラーは、SOAP Agentメッセージ・ハンドラー・フレームワークで使用できます。 特定のSOAP Agentサービスにメッセージ・ハンドラーを追加するには、SOAPAgentService.propertiesファイルに'service.handlers.サービス名' エントリーを追加します。

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 ;
    }
}