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.

@Endpoint
@Transactional
public class MySoapServerImpl implements MySoapServer {

    @Autowired
    private SaajSoapMessageFactory saajMessageFactory;
    
    @Autowired
    private ApplicationContext ctx;
    
    @Override
    @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);
        
        MessageContextHolder.getMessageContext().setResponse(soapMessage);
    
        return response;
    }
}

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



    
    
        
            
        
    

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

        MessageContextHolder.setMessageContext(messageContext);
        //messageContext.getRequest().writeTo(System.out);
        return super.handleRequest(messageContext, endpoint);
    }
   
    @Override
    public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
       
        MessageContextHolder.removeMessageContext();
        //messageContext.getResponse().writeTo(System.out);
        return super.handleResponse(messageContext, endpoint);
    }
   
    public boolean handleFault(MessageContext messageContext, Object endpoint) {
       
        MessageContextHolder.removeMessageContext();
        return super.handleFault(messageContext, endpoint);
    }
}
public final class MessageContextHolder {
    private static ThreadLocal<MessageContext> threadLocal = new ThreadLocal<MessageContext>() {
        @Override
        protected MessageContext initialValue() {
            return null;
        }
    };

    private MessageContextHolder() {
    }

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

    public static void setMessageContext(MessageContext context) {
        threadLocal.set(context);
    }

    public static void removeMessageContext() {
        threadLocal.remove();
    }
}

Laisser une réponse

«     »