Как использовать прямую потоковую передачу для SOAP с Spring-WS? - PullRequest
16 голосов
/ 02 марта 2011

Мы хотим включить прямую потоковую передачу наших полезных данных в конечных точках веб-сервиса.Мы должны обработать большой объем данных и хотим передавать данные во время обработки.

Мы используем spring-ws-core версии 2.0.0 и используем PayloadRootQNameEndpointMapping в качестве средства отображения конечных точек.В качестве фабрики сообщений мы используем AxiomSoapMessageFactory.Мы реализуем StreamingPayload и соответствующий writeTo(XMLStreamWriter writer) метод, который мы используем для записи нашей полезной нагрузки (в соответствии с билетом Spring-ws JIRA, * ​​1007 * SWS-352 ).

Это работаетхорошо без каких-либо ошибок, но мы хотели, чтобы потоковое прямо!Это, по-видимому, невозможно.Мы сделали простой тест, в котором мы потратили некоторые данные для оценки поведения.

writer.writeStartElement("exampleResponse")

10000.times
{
    writer.writeStartElement("example")
    writer.writeEndElement()    
}

writer.writeEndElement()

Мы предполагали, что это будет напрямую передано потребителю / клиенту, поэтому заголовок мыла уже записан нашему писателю и закрываетсяпосле завершения конечной точки.К сожалению, это невозможно, поток не может быть использован напрямую!Поток обернут в ByteArrayInputStream, найденный в источнике spring-ws.

Реализация StreamingOMDataSource показывает это (можно посмотреть в springs FishEye ).StreamingOMDataSource вызывает вашу реализацию StreamingPayload и предоставляет вам средство записи для этого.

public XMLStreamReader getReader() throws XMLStreamException {
   ByteArrayOutputStream bos = new ByteArrayOutputStream();
   serialize(bos, null);

   ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
   return StAXUtils.createXMLStreamReader(bis);
}

Метод #serialize() создает XMLStreamWriter с ByteArrayOutputStream и вызывает полезную нагрузку для включения записи, как описановыше.

public void serialize(OutputStream output, OMOutputFormat format) 
       throws XMLStreamException
{
   XMLStreamWriter streamWriter;
   if ([...]) {
      // Create stream writer with defined charset
   }
   else {
       streamWriter = StAXUtils.createXMLStreamWriter(output);
   }
   serialize(streamWriter);
}

public void serialize(XMLStreamWriter xmlWriter) throws XMLStreamException {
   payload.writeTo(xmlWriter);
   xmlWriter.flush();
}

Так что это не для меня.Можно ли добиться прямой потоковой передачи?Есть идеи для этого?Заранее спасибо!


Обновление : Я наконец создал билет JIRA (SWS-704) для Spring WS.Если вы хотите, чтобы это было реализовано, рассмотрите возможность просмотра / голосования на странице JIRA.Надеюсь, мы получим хотя бы полезный ответ.

Ответы [ 3 ]

4 голосов
/ 21 июля 2011

Вы также должны отключить кэширование полезной нагрузки:

<bean id="messageFactory" 
      class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
     <property name="payloadCaching" value="false"/>
</bean> 

С этим параметром мы наконец можем выполнить прямую потоковую передачу для SOAP с Spring WS!

2 голосов
/ 05 апреля 2011

Вы не можете (никогда не должны) передавать данные внутри веб-службы, как при непрерывной отправке XML через HTTP-соединение в одном запросе веб-службы с течением времени.Вам нужно будет совершить много звонков через веб-сервис или собрать несколько звонков в один.

Если вам нужна высокая производительность, веб-сервисы не очень хороши.Но вы можете вручную оптимизировать простые веб-сервисы, это не так сложно.Но переключение на другой транспортный формат будет более выгодным, если вам потребуется более высокая производительность.Я бы по-прежнему держал вещи поверх HTTP - особенно если у вас есть некоторые требования к аутентификации.

0 голосов
/ 10 марта 2011

Я могу думать только о хаке для этого - стеки (cxf, spring ws и т. Д.) Будут буферизовать все сообщение, так как они должны проверять xml ответа, чтобы иметь возможность вычислять криптографические ключи, если включена защита и т. Д.

Так что взломать было бы написать свой собственный контроллер сервлетов / пружин, который бы обрабатывал этот конкретный ответ и передавал поток мыльного конверта, затем вашу полезную нагрузку, а затем конечный тег мыльного конверта. Предполагается, что у вас нет требований к WSS.

...