Returning WS-attachments with Spring Web Service 1.5.9

30 July 2012, by Baptiste Autin

Since Spring WS version 2.0, it is straightforward to get a MessageContext object from within the endpoints, and therefore to retrieve/return attachments from/in SOAP messages.

But with the previous release (1.5.9), the one I still have to use at work, it is not that simple.
So I started from an idea given by another Java blogger, explained here, which consists in intercepting the SOAP request, and saving the MessageContext in a ThreadLocal.
In his post, the author of that trick shows how to extract an attachment sent by the client to the web service.
I am going to show you the opposite way: how to add an attachment in the web service response.

public class MySoapServerImpl implements MySoapServer {

    private SaajSoapMessageFactory saajMessageFactory;
    private ApplicationContext ctx;
    @PayloadRoot(namespace = "some namespace", localPart = "FindSomethingRequest")
    public FindSomethingResponse FindSomething(FindSomethingRequest request) throws InvalidParameterException, IOException {
        final FindSomethingResponse response = new FindSomethingResponse();
        WebServiceMessage message = saajMessageFactory.createWebServiceMessage();
        SoapMessage soapMessage = (SoapMessage) message;
        File file = ctx.getResource("foo.jpg").getFile();    // here is the file we want to send back
        soapMessage.addAttachment(file.getName(), file);
        return response;

And as a reminder, this is how to intercept and save a SOAP message in a ThreadLocal:


public class MsgCtxInterceptorAdapter extends EndpointInterceptorAdapter {
    public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {

        return super.handleRequest(messageContext, endpoint);
    public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
        return super.handleResponse(messageContext, endpoint);
    public boolean handleFault(MessageContext messageContext, Object endpoint) {
        return super.handleFault(messageContext, endpoint);
public final class MessageContextHolder {
    private static ThreadLocal<MessageContext> threadLocal = new ThreadLocal<MessageContext>() {
        protected MessageContext initialValue() {
            return null;

    private MessageContextHolder() {

    public static MessageContext getMessageContext() {
        return threadLocal.get();

    public static void setMessageContext(MessageContext context) {

    public static void removeMessageContext() {

Laisser une réponse

«     »