Announcement Announcement Module
Collapse
No announcement yet.
How do I add an attachment to a response payload? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How do I add an attachment to a response payload?

    I'm building a Web Services server that's designed to share content. I'm struggling to find any documentation on how to attach something to the response payload. Ideally I'd be able to continue to use JAXB to convert the current response payload and simply tack on an attachment to the SOAP message, if that's not possible I can probably live with it.

    My service resembles something like this:

    Code:
    @Endpoint
    public class Service{
    
        @PayloadRoot(namespace = "http://foo.com/coffee", localPart = "order")
        @ResponsePayload
        public Coffee getCoffee(@RequestPayload Order order){
            return new Coffee("Hot Joe");
        }
    
    }
    But suppose I want to attach a picture of a cup of coffee to the response, where and how do I do that?

    As an aside, the examples that ship with Spring-WS show how to use the client to send an attachment, but not how the server should respond with one (which is what I'm asking about here).

  • #2
    Figured it out...the documentation in Spring-WS is particularly light on this topic, and it's actually pretty easy to add a SOAP attachment. I'll make a few assumptions:

    1. Your WSDL correctly specifies the `mime:multipartRelated` on the output message
    2. We're going to use the Saaj SOAP message factory

    Attachments reside in the MimeContainer on the SOAP message. To get this container, we need to manually construct the SOAP response, well, just part of it. Doing that looks like this:

    Code:
        SaajSoapMessageFactory factory = new SaajSoapMessageFactory(
            javax.xml.soap.MessageFactory.MessageFactory.newInstance());
        SaajSoapMessage message = factory.createWebServiceMessage();
    Now we need a DataHandler for our picture:

    Code:
        DataHandler handler = new DataHandler(
            new URLDataSource(
                Service.class.getResource("coffee.jpg")));
    
        message.addAttachment("picture", handler);
    Okay, content: check, message: check, hm, still need to get the response to go out. The tricky part here is that we need to bring in the `MessageContext` so that we can set *this* particular message to be the one we respond with, we do that by editing our definition of `getCoffee`:

    Code:
        public Coffee getCoffee(@RequestPayload Order order, MessageContext context)
    Putting it all together:

    Code:
        @Endpoint
        public class Service{
    
            private SaajSoapMessageFactory saajMessageFactory; // dependency inject this
        
            @PayloadRoot(namespace = "http://foo.com/coffee", localPart = "order")
            @ResponsePayload
            public Coffee getCoffee(@RequestPayload Order order, MessageContext context){
                DataHandler handler = new DataHandler(
                    new URLDataSource(
                        Service.class.getResource("coffee.jpg")));
    
                SaajSoapMessage message = saajMessageFactory.createWebServiceMessage();
                message.addAttachment("picture", handler);
    
                context.setResponse(message);
                    
                return new Coffee("Hot Joe");
            }
    
            public void setSaajMessageFactory(SaajMessageFactory saajMessageFactory){
                this.saajMessageFactory = saajMessageFactory;
            }
    
            public SaajMessageFactory getSaajMessageFactory(){
                return saajMessageFactory;
            }
        
        }
    For good measure, here's the beans dependency injection for getting a `SaajMessageFactory`:

    Code:
        <bean id="soapMessageFactory" class="javax.xml.soap.MessageFactory" factory-method="newInstance" />
        <bean id="saajMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory.SaajSoapMessageFactory">
            <constructor-arg ref="soapMessageFactory" />
        </bean>
    
        <bean id="myService" class="Service">
            <property name="saajMessageFactory" ref="saajMessageFactory" />
        </bean>

    Comment


    • #3
      Which part of the WSDL file should i specify the multipart/related type?

      Comment

      Working...
      X