Подтвердить что ты не робот

Как использовать прямое потоковое воспроизведение для SOAP с помощью Spring -WS?

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

Мы используем spring -ws-core, в версии 2.0.0 и используем PayloadRootQNameEndpointMapping в качестве средства отображения конечных точек. В качестве сообщения factory мы используем AxiomSoapMessageFactory. Мы реализуем StreamingPayload и соответствующий метод writeTo(XMLStreamWriter writer), который мы используем для написания нашей полезной нагрузки (согласно биту JARA spring -ws 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. Надеюсь, мы получим хотя бы полезный ответ.

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

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