Добрый день.
Имеется SOAP веб-сервис, написанный на Spring + Spring-WS.
В качестве реализации сообщений используется SAAJ.
Столкнулись с проблемой, что большие запросы (сообщение с base64 вложением порядка 30 МБ и более) обрабатываются ну ОЧЕНЬ долго, что приводит к подвисанию всего сервиса. Смотрел в дебагере, "умирает" в конструкторе SaajSoapMessage.
Соответственно примерных варианта два:
1) Прикрутить MTOM, однако практически ничего цельного по теме Spring-ws + MTOM не нашел, и в офф. доках тоже
2) Заменить Saaj на Axiom — согласно офф. док. подменил MessageFactory, однако при формировании ответа столкнулся с двумя проблемами:
2.1) SOAPMessage soapMessage = ((AxiomSoapMessage)message).getAxiomMessage();
StringWriter stringWriter = new StringWriter();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(soapMessage.getSAXSource(true), new StreamResult(stringWriter));
return stringWriter.toString();
На предпоследней строке падает с ошибкой org.apache.axiom.om.OMException: Element prefix from data source is 'ns5', not the expected '' (погуглив попал на багтрекер Axis, где написано ,что это якобы баг спринги...)
2.2) На выходе в SoapUI выводит вот такое:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
SOAPAction: ""
Accept: text/xml
Content-Type: text/xml;charset=UTF-8
Transfer-Encoding: chunked
Date: Tue, 18 Aug 2015 11:28:29 GMT
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="
http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/><soapenv:Body
а куда остальная часть ответа делась? или это SoapUI так обрабатывает криво?
Подскажите пож-та, как решить проблему и куда лучше двигаться (может, например, вообще заменить Spring-WS на JAX-WS) ...
Здравствуйте, tavr, Вы писали:
T>Вы уперлись в ограничения, которые в первую очередь связаны с использованием SOAP.
T>Я бы задумался о переезде на бинарный формат.
T>Пересылка больших вложений также подразумевает другой механизм, переход на потоковую и асинхронную модель закачки-докачки-валидации.
Увы, но необходимо использовать именно SOAP.
Пытаюсь все-таки реализовать работу с MTOM. Нашел
топик
Добавил флаг <property name="mtomEnabled" value="true"/> в маршаллер:
<bean id="smevMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="smev.ws.beans"/>
<property name="mtomEnabled" value="true"/>
</bean>
<sws:annotation-driven marshaller="smevMarshaller" unmarshaller="smevMarshaller"/>
В SoapUI настроил передачу через MTOM, кинул себе запрос, вот фрагмент:
<rev:AppDocument>
<rev:RequestCode>req_6d423abf-2fbc-418e-971c-2de10288533f</rev:RequestCode>
<rev:BinaryData><inc:Include href="cid:req_6d423abf-2fbc-418e-971c-2de10288533f.zip" xmlns:inc="http://www.w3.org/2004/08/xop/include"/></rev:BinaryData>
</rev:AppDocument>
Вот класс:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AppDocumentType", namespace = "http://smev.gosuslugi.ru/rev120315", propOrder = {
"requestCode",
"binaryData"
})
public class AppDocumentType {
@XmlElementRef(name = "RequestCode", namespace = "http://smev.gosuslugi.ru/rev120315", type = JAXBElement.class)
protected JAXBElement<String> requestCode;
@XmlElementRef(name = "BinaryData", namespace = "http://smev.gosuslugi.ru/rev120315", type = JAXBElement.class)
protected JAXBElement<byte[]> binaryData;
...
}
Однако после анмаршаллинга поле binaryData пустое. Что я делаю не так?
Проблема решена, как будет свободное время, постараюсь отписаться, может кому и пригодится.