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)キーワードを使用します。

メッセージ・ハンドラー構成

...

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 ;

...

    

...

}

...

}

...