Как добавить вложение в полезную нагрузку ответа в Spring-WS? - PullRequest
5 голосов
/ 22 июня 2011

Я создаю сервер веб-служб, предназначенный для обмена контентом. Я хотел бы предоставить контент через ответ 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");
    }

}

Но предположим, что я хочу прикрепить изображение чашки кофе к ответу, где и как это сделать?

edit: кроме того, примеры, поставляемые с Spring-WS, показывают, как использовать клиент для отправки вложения, а не то, как сервер должен отвечать одним (о чем я здесь и спрашиваю).

1 Ответ

13 голосов
/ 23 июня 2011

Документация в Spring-WS особенно легка в этом вопросе, и на самом деле довольно просто добавить вложение SOAP.Я сделаю несколько предположений:

  1. Ваш WSDL правильно указывает mime:multipartRelated в выходном сообщении
  2. Мы собираемся использовать фабрику сообщений Saaj SOAP

Вложения находятся в MimeContainer в сообщении SOAP.Чтобы получить этот контейнер, нам нужно вручную создать SOAP-ответ, ну, в общем, его часть.Это выглядит следующим образом:

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

Теперь нам нужен DataHandler для нашей картинки:

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

message.addAttachment("picture", handler);

Хорошо, содержимое: проверка, сообщение: проверка, хм, все еще нужно получитьответ, чтобы выйти.Сложность заключается в том, что нам нужно ввести MessageContext, чтобы мы могли установить это конкретное сообщение тем, на которое мы отвечаем, мы делаем это, редактируя наше определение getCoffee:

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

Собираем все воедино:

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

}

Для примера, вот инъекция зависимостей бинов для получения 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>
...