<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bytearray - Programming, Computers and Technology &#187; raw soap envelope</title>
	<atom:link href="http://bytearray.brixtonjunkies.com/tag/raw-soap-envelope/feed/" rel="self" type="application/rss+xml" />
	<link>http://bytearray.brixtonjunkies.com</link>
	<description></description>
	<lastBuildDate>Tue, 03 Nov 2009 11:52:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>CXF Raw SOAP Envelope via Interceptor</title>
		<link>http://bytearray.brixtonjunkies.com/2009/11/03/cxf-raw-soap-envelope-via-interceptor/</link>
		<comments>http://bytearray.brixtonjunkies.com/2009/11/03/cxf-raw-soap-envelope-via-interceptor/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 11:18:43 +0000</pubDate>
		<dc:creator>alchemist</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Web/HTML]]></category>
		<category><![CDATA[cxf]]></category>
		<category><![CDATA[interceptor]]></category>
		<category><![CDATA[raw soap envelope]]></category>
		<category><![CDATA[soap]]></category>

		<guid isPermaLink="false">http://bytearray.brixtonjunkies.com/?p=675</guid>
		<description><![CDATA[Recently I started using the CXF SOAP library from Apache and was stumped on a simple problem, that being, how to view/modify a raw SOAP envelope. This sounds like a relatively simple task (not too bad when you know how) however it does in fact require some know-how. The CXF SOAP library gives you access [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;"><img class="size-full wp-image-318 alignleft" title="CXF SOAP" src="http://bytearray.brixtonjunkies.com/wp-content/uploads/2009/11/soap-bar.jpg" alt="CXF SOAP" width="144" height="144" />Recently I started using the <a href="http://cxf.apache.org" target="_blank" rel="nofollow">CXF</a> SOAP library from Apache and was stumped on a simple problem, that being, how to view/modify a raw SOAP envelope. This sounds like a relatively simple task <em>(not too bad when you know how)</em> however it does in fact require some know-how.</p>
<p>The CXF SOAP library gives you access to all parts of the SOAP request and response life-cycle <em>(via HTTP)</em> using CXF <strong>Interceptors</strong>. The different points in time are referred to as <strong>phases</strong> and an interceptor can be placed at any one of the defined phases and automatically gain access to the SOAP message object and it&#8217;s current state.</p>
<p>For this example I have chosen <strong>Phase.RECEIVE</strong> which is one of the first phases which is essentially unprocessed by the CXF SOAP stack, which means I have free rain to pre-process the SOAP envelope <em>(if I want to)</em>. Particularly handy if you need to maintain backwards compatibility with old SOAP API&#8217;s, poorly defined complex SOAP objects, dodgy WSDL definitions or maybe you simply want to view raw SOAP envelope <em>(handy for debugging)</em>.</p>
<p>The crux to this problem is manipulating InputStream&#8217;s, once an InputStream has been read it is not available, which obviously causes a problem as the rest of the CXF SOAP stack expects it to be available. The solution is to use the CXF provided  <strong>CachedOutputStream</strong> and <strong>IOUtils.copy</strong> which takes a cache copy of the InputStream making it available for future use <img src='http://bytearray.brixtonjunkies.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Once the Interceptor is implemented all that remains is to add it to the CXF SOAP client pror to usage. </p>
<p>This is an example of gaining access to an incoming client SOAP envelope, the interceptor could quite easily be in the <strong>sent phase</strong> or even part of the SOAP server implementation&#8230;it&#8217;s up to you.</p>
<pre class="brush: java; title: ; notranslate">
package CXFSoap;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;

public class PacketInterceptor extends AbstractPhaseInterceptor&amp;amp;lt;Message&amp;amp;gt;{

	public PacketInterceptor(){
		super(Phase.RECEIVE);
	}

	public void handleMessage(Message message) throws Fault{
		// Get the supplied SOAP envelope in the form of an InputStream
		InputStream inputStream = message.getContent(InputStream.class);

		if (inputStream != null){
			String processedSoapEnv = &amp;amp;quot;&amp;amp;quot;;
			// Cache InputStream so it can be read independently
			CachedOutputStream cachedInputStream = new CachedOutputStream();
			try {
				IOUtils.copy(inputStream,cachedInputStream);
				inputStream.close();
				cachedInputStream.close();

				InputStream tmpInputStream = cachedInputStream.getInputStream();
				try{
					String inputBuffer = &amp;amp;quot;&amp;amp;quot;;
					int data;
					while((data = tmpInputStream.read()) != -1){
						byte x = (byte)data;
						inputBuffer += (char)x;
					}
					/**
					  * At this point you can choose to reformat the SOAP
					  * envelope or simply view it just make sure you put
 					  * an InputStream back when you done (see below)
 					  * otherwise CXF will complain.
					  */
					processedSoapEnv = fixSoapEnvelope(inputBuffer);
				}
				catch(IOException e){

				}
			}
			catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			// Re-set the SOAP InputStream with the new envelope
			message.setContent(InputStream.class,new ByteArrayInputStream(processSoapEnv.getBytes()));

			/**
			 * If you just want to read the InputStream and not
			 * modify it then you just need to put it back where
			 * it was using the CXF cached inputstream
			 *
			 * message.setContent(InputStream.class,cachedInputStream.getInputStream());
			*/
		}
	}

	private String fixSoapEnvelope(String xml){
		...
	}
}
</pre>
<pre class="brush: java; title: ; notranslate">

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import Stuff.StuffObj;
import CXFSoap.PacketInterceptor;
import CXFSoap.VIPCoreAPI;

public class CXFTest{

	    public static void main(String args[]) throws Exception{
	    		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
		    	factory.setServiceClass(VIPCoreAPI.class);
		    	factory.setAddress(&amp;amp;quot;http://x.x.x.x/SOAP/API&amp;amp;quot;);
		    	factory.setWsdlLocation(&amp;amp;quot;http://x.x.x.x/SOAP/API?wsdl&amp;amp;quot;);
		    	factory.setUsername(&amp;amp;quot;xxx&amp;amp;quot;);
		    	factory.setPassword(&amp;amp;quot;xxx&amp;amp;quot;);

		    	/**
		    	 * This is the important part, the interceptor needs
		    	 * to be added to the CXF SOAP client prior to
		    	 * the SOAP call being made.
		    	 */
		    	factory.getInInterceptors().add(new PacketInterceptor());

		    	API client = (API)factory.create();
		    	StuffObj stuff = client.getStuff();
		    	System.out.print(stuff.toString());
	    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://bytearray.brixtonjunkies.com/2009/11/03/cxf-raw-soap-envelope-via-interceptor/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

