Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
420 views
in Technique[技术] by (71.8m points)

java - How do I add an attachment to a response payload in Spring-WS?

I'm building a Web Services server that's designed to share content. I'd like to serve the content through a SOAP response containing an attachment. Right now, I'm using Spring WS to handle requests and serve responses.

My service resembles something like this:

@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?

edit: 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).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

SaajSoapMessageFactory factory = new SaajSoapMessageFactory(
    javax.xml.soap.MessageFactory.newInstance());
SaajSoapMessage message = factory.createWebServiceMessage();

Now we need a DataHandler for our picture:

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:

public Coffee getCoffee(@RequestPayload Order order, MessageContext context)

Putting it all together:

@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:

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

<bean id="myService" class="Service">
    <property name="saajMessageFactory" ref="saajMessageFactory" />
</bean>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...