Skip to content

Instantly share code, notes, and snippets.

@MAOliver
Created September 27, 2012 13:35
Show Gist options
  • Save MAOliver/3794028 to your computer and use it in GitHub Desktop.
Save MAOliver/3794028 to your computer and use it in GitHub Desktop.
JAX-RS / Jersey Implementation of a SOAP consumer / producer. This lets you annotate your methods with application/soap+xml for soap 1.2 or text/xml for soap 1.1 and use it just like any other media type. Original idea from http://aruld.info/soap-over-res
package com.mao.jaxb.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.lang.exception.ExceptionUtils;
/**
* Base class for read/write operations for SOAP messages when marshalling/unmarshalling XML
*
* @author moliver
* @since 7/21/11 11:33 AM
*/
public abstract class AbstractSoapProvider implements MessageBodyWriter<SOAPMessage>, MessageBodyReader<SOAPMessage>
{
@Override
public boolean isWriteable( Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType )
{
return SOAPMessage.class.isAssignableFrom( aClass );
}
@Override
public long getSize( SOAPMessage soapMessage, Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType )
{
return -1;
}
@Override
public void writeTo( SOAPMessage soapMessage, Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> stringObjectMultivaluedMap, OutputStream outputStream ) throws IOException, WebApplicationException
{
try
{
soapMessage.writeTo( outputStream );
}
catch( SOAPException e )
{
ExceptionUtils.getFullStackTrace( e );
}
}
@Override
public boolean isReadable( Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType )
{
return aClass.isAssignableFrom( SOAPMessage.class );
}
protected SOAPMessage modifyMessage( String soapProtocol, InputStream inputStream ) throws SOAPException
{
MessageFactory messageFactory = MessageFactory.newInstance( soapProtocol );
StreamSource messageSource = new StreamSource( inputStream );
SOAPMessage message = messageFactory.createMessage();
SOAPPart soapPart = message.getSOAPPart();
soapPart.setContent( messageSource );
message.saveChanges();
return message;
}
}
package com.mao.jaxb.util;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
/**
* Provides an implementation for {@link AbstractSoapProvider} that allows conversion of {@link java.io.InputStream} of {@link javax.xml.soap.SOAPMessage} with {@link javax.xml.soap.SOAPConstants#SOAP_1_1_PROTOCOL}
*
* @author moliver
* @since 7/21/11 11:39 AM
*/
@Provider
@Consumes( "text/xml" )
@Produces( "text/xml" )
public class Soap11Provider extends AbstractSoapProvider
{
@Override
public SOAPMessage readFrom( Class<SOAPMessage> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream ) throws IOException, WebApplicationException
{
try
{
return modifyMessage( SOAPConstants.SOAP_1_1_PROTOCOL, entityStream );
}
catch( SOAPException e )
{
throw new IOException( e );
}
}
}
package com.mao.jaxb.util;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
/**
* Provides an implementation for {@link AbstractSoapProvider} that allows conversion of {@link java.io.InputStream} of {@link javax.xml.soap.SOAPMessage} with {@link javax.xml.soap.SOAPConstants#SOAP_1_2_PROTOCOL}
*
* @author moliver
* @since 7/21/11 11:39 AM
*/
@Provider
@Consumes( "application/soap+xml" )
@Produces( "application/soap+xml" )
public class Soap12Provider extends AbstractSoapProvider
{
@Override
public SOAPMessage readFrom( Class<SOAPMessage> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream ) throws IOException, WebApplicationException
{
try
{
return modifyMessage( SOAPConstants.SOAP_1_2_PROTOCOL, entityStream );
}
catch( SOAPException e )
{
throw new IOException( e );
}
}
}
@MAOliver
Copy link
Author

I've actually replaced axis in my applications by using this. I greatly prefer JAXB / Jersey/JAX-RS even for my SOAP communications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment