如何在Spring-WS中为响应有效负载添加附件?

Mar*_*iot 5 java spring soap spring-ws

我正在构建一个旨在共享内容的Web服务服务器.我想通过包含附件的SOAP响应来提供内容.现在,我正在使用Spring WS处理请求并提供响应.

我的服务类似于以下内容:

@Endpoint
public class Service{

    @PayloadRoot(namespace = "http://foo.com/coffee", localPart = "order")
    @ResponsePayload
    public Coffee getCoffee(@RequestPayload Order order){
        return new Coffee("Hot Joe");
    }

}
Run Code Online (Sandbox Code Playgroud)

但是假设我想在回复中附上一杯咖啡的图片,我在哪里以及如何做到这一点?

编辑:另外,Spring-WS附带的示例显示了如何使用客户端发送附件,而不是服务器应该如何响应(这是我在这里问的问题).

Mar*_*iot 13

Spring-WS中的文档对这个主题特别轻松,实际上很容易添加SOAP附件.我会做一些假设:

  1. 您的WSDL正确指定mime:multipartRelated了输出消息
  2. 我们将使用Saaj SOAP消息工厂

附件驻留在SOAP消息的MimeContainer中.要获得此容器,我们需要手动构建SOAP响应,这只是其中的一部分.这样做看起来像这样:

SaajSoapMessageFactory factory = new SaajSoapMessageFactory(
    javax.xml.soap.MessageFactory.newInstance());
SaajSoapMessage message = factory.createWebServiceMessage();
Run Code Online (Sandbox Code Playgroud)

现在我们需要一个DataHandler用于我们的图片:

DataHandler handler = new DataHandler(
    new URLDataSource(
        Service.class.getResource("coffee.jpg")));

message.addAttachment("picture", handler);
Run Code Online (Sandbox Code Playgroud)

好的,内容:检查,消息:检查,嗯,还是需要得到响应才能出去.这里棘手的部分是我们需要引入,MessageContext以便我们可以将此特定消息设置为我们响应的消息,我们通过编辑我们的定义来实现getCoffee:

public Coffee getCoffee(@RequestPayload Order order, MessageContext context)
Run Code Online (Sandbox Code Playgroud)

把它们放在一起:

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

}
Run Code Online (Sandbox Code Playgroud)

为了更好的衡量,这里是bean依赖注入获取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>
Run Code Online (Sandbox Code Playgroud)