Page History
...
When the SOAP Agent command OPEN SERVICE ( servicename ) is executed the service class and message handler file are assigned to the executing program.
service.test=com.acme.service.soap.TestService
service.handlers.test=handlers/soapagent-handlers.xml
...
If the parameter value attribute contains a value within open and close curly brackets, then the value is assumed to be a LANSA field name and the value of the LANSA field is passed to the handler. Use the SERVICE_EXCHANGE(*FIELD) keyword on the CALL command to make LANSA fields available to the handler class.
Message
...
Handler Configuration
<?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>
Example Message Handler Class
...
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 ()
...
{
...
/*
...
Optional - this over-rides init stub in BasicHandler
...
Firstly, init is called on all handlers
...
Secondly, invoke is called on all handlers
...
Finally, cleanup is called on all handlers
...
You could pass information between handlers by using:
...
MessageContext - setProperty ( String name, Object value )
...
MessageContext - Object value getProperty ( String name )
...
*/
...
}
...
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 ()
...
{
...
/*
...
Optional - this over-rides cleanup stub in BasicHandler
...
*/
...
if ( m_trace != null )
...
{
...
m_trace.println ( "MyHandler: cleanup" ) ;
...
}
...
}
...
private final void traceOptions ()
...
{
...
/*
...
The following properties are from the handler parameters
...
*/
...
String value = (String)getOption ( "acme.keyword" ) ;
...
/*
...
The following properties are supplied by the JSM service
...
*/
...
String type = (String)getOption ( "jsm.handler.property.type" ) ;
...
String service = (String)getOption ( "jsm.handler.property.service" ) ;
...
String operation = (String)getOption ( "jsm.handler.property.operation" ) ;
...
/*
...
CALL command
...
*/
...
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" ) ;
...
}
...
/*
...
Trace message - output is dependent on internal form
...
*/
...
// traceMessage ( message ) ;
...
/*
...
SOAP Part
...
*/
...
SOAPPart soapPart = (SOAPPart)message.getSOAPPart () ;
...
int form = soapPart.getCurrentForm () ;
...
if ( m_trace != null )
...
{
...
m_trace.println ( "MyHandler: current message form : ", FORM_NAMES[form] ) ;
...
}
...
/*
...
SOAP Envelope - the internal form is converted to SOAPEnvelope
...
*/
...
SOAPEnvelope envelope = soapPart.getAsSOAPEnvelope () ;
...
// traceEnvelope ( envelope ) ;
...
/*
...
Handle request or response
...
*/
...
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...
{
...
/*
...
This needs to be the last message change
...
Message.writeTo -> SOAPPart.writeTo methods will sent bytes as is
...
This approach runs the risk of a FORM conversion taking place on the byte[] content
...
*/
...
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
...
{
...
/*
...
With this example, I am using byte content from a file
...
But you could have serialized a Document to a byte[] in-memory
...
Or created a String and used that as the content argument
...
etc..
...
*/
...
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 () ;
...
/*
...
Change document
...
*/
...
byte[] content = serializeDocument ( document ) ;
...
Message requestMessage = new Message ( content ) ;
...
messageContext.setRequestMessage ( requestMessage ) ;
...
}
...
private final void setResponseMessage1 ( MessageContext messageContext ) throws Exception
...
...
{
/*
...
With this example, I am using byte content from a file
...
But you could have serialized a Document to a byte[] in-memory
...
Or created a String and used that as the content argument
...
etc..
...
*/
...
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 ;
...
}
...
/*
...
This uses MessageElement - getAsDocument
...
- getAsDocument
...
- getAsString
...
Converts element to String and parser into a Document
...
*/
...
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 )
...
{
...
/*
...
Interface
...
*/
...
}
...
}
...
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 ;
...
}
...
}