Retourner des pièces jointes avec Spring Web Service 1.5.9

Baptiste Autin, le 30 juillet 2012

Depuis la version 2.0 de Spring Web Service, il est facile d’accéder à l’objet MessageContext, et donc de récupérer ou de retourner des attachments dans des messages SOAP.

Mais avec la version précédente (1.5.9), celle que je suis encore contraint d’utiliser à mon travail, c’est plus délicat.
Je suis donc parti d’une astuce donnée par un autre blogueur, Osvaldas Grigas, consistant à intercepter les appels SOAP, et à mémoriser dans un ThreadLocal une
référence à l’objet MessageContext (exposé par l’interface EndpointInterceptor).

Dans son post, l’auteur de cette astuce montre comment récupérer un fichier transmis par le client vers le service web.
Je vais vous montrer le chemin inverse, c’est à dire comment intégrer un attachment dans la réponse du web service vers le client :

@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;
    }
}

Et pour rappel, voici comment intercepter et enregistrer un message SOAP dans un 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

«     »