2015-09-25 7 views
2

я использую пружинные интеграции Int-WS: исходящем-шлюз для чтения файлов (PDF/...) от веб-сервиса с XOP/MTOMMTOM привязанность устремляется в канал

Он работает правильно и получить поток из и я могу записать их на диск.

Но SI весна-WS сохраняет файлы в памяти во время передачи: получение 30 файлов 60 МБ вместе заполняет память и не удается (даже если в вызывающем методе я прочитал поток с bufferedStream 128kB в то время,).

Я хочу, чтобы иметь возможность передавать N файлов с помощью «N * fileSize> availableMemory», потоковое выделение фрагментов.

xml (и объект ответа) содержит другую информацию, например название и т. Д., А «файл» - это InputStream из DataHandler.

EDIT: Это не было ошибкой интеграции с интеграцией. Это случается также с автономным клиентом spring-ws.

мои бобы:

<bean id="mtomMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> 
     <property name="contextPath" value="aaaaa.bb.filestreamer" /> 
     <property name="mtomEnabled" value="true" /> 
</bean> 

Мои SI конфигурации:

<int:logging-channel-adapter id="logger" level="DEBUG" log-full-message="true"/> 

<!-- All my channels are like this: --> 
<int:channel id="singleFileRespChannel"><int:interceptors><int:wire-tap channel="logger"/></int:interceptors></int:channel> 

<int:gateway id="filewsEntry" 
     service-interface="aaaaa.ws.FileServiceGateway" 
     default-reply-timeout="5000" > 
      <int:method name="getSingleFile" request-channel="singleFileReqChannel" reply-channel="singleFileRespChannel" /> 
    </int:gateway> 

<int-ws:outbound-gateway id="singleFileMarshallingGateway"  
    request-channel="singleFileReqChannel" reply-channel="singleFileRespChannel" 
    requires-reply="true" 
    uri="${filews.singleFile.wsURI}" marshaller="mtomMarshaller" 
    unmarshaller="mtomMarshaller" > 
</int-ws:outbound-gateway> 

Я попытался также с аксиомой:

<bean id="axiomMessageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory"> 
     <property name="payloadCaching" value="false" /> 
     <property name="attachmentCaching" value="false" /> 
     <property name="attachmentCacheThreshold" value="1024"/> 
     <property name="attachmentCacheDir" value="D:/tmp/cache"></property> 
    </bean> 

Но, кроме кэширования файлов на диске, это то же самое : JVM всегда использует одно и то же количество памяти (кучи).

Я думал о S-I. сплиттер, который вернет куски на карте ... но для этого ему все равно придется читать весь файл.

Может ли результат быть «потоковым» через каналы интеграции пружины абоненту без нагрузки в памяти?

Любая идея о том, как я могу это сделать?

Edit: добавление запрашиваемой информации: в JUnit @Test я называю обслуживание в Runnable.run() (начиная с 30 потоков) для имитации одновременных запросов от клиентов. Используемая память растет до максимального (2gb) означает, что он получает все файлы в памяти:

Здесь вызывающем абоненте часть кода:

try{ 
     FileResponse sfresp = service.getSingleFile(sfreq); // CALL S.I. GW 

     logger.warn("SINGLEFILE STREAM: "+ sfreq.getFile().getFileId()); 

     InputStream in=new BufferedInputStream(sfresp.getFileAttachment().getFile().getInputStream()); 

     logger.warn("writing the stream"); 
     byte[] buffer = new byte[1024]; 
     int bytesRead; 
     try{ 
      bytesRead = in.read(buffer); 
      logger.warn("just read "+bytesRead+" Bytes from file : " + new String(buffer,"ASCII")); 

     }catch (IOException e) { 
      logger.error("FILE I/O ERROR"+e.getLocalizedMessage()); 
     }finally{ 
      in.close(); 
     } 
}catch....etc etc 

Первые результаты появляется после того, как много времени (30 секунд), поэтому кажется, что конечная точка получает весь файл перед передачей потока обратно вызывающему.

EDIT

Я отлажена а, в то время как я не могу понять, почему это получить все 60-Megs файл, а не только в нескольких байтах я просил, и это делает его еще до того, я начала читать поток:

2015-09-28 11:20:32,725|WebServiceTemplate|Sent request [AxiomSoapMessage] 
2015-09-28 11:20:32,741|OMOutputFormat|Start getContentType: OMOutputFormat [ mimeBoundary =null rootContentId=null doOptimize=false doingSWA=false isSOAP11=true charSetEncoding=UTF-8 xmlVersion=null contentType=null ignoreXmlDeclaration=false autoCloseWriter=false actionProperty=null optimizedThreshold=0] 
2015-09-28 11:20:32,741|OMOutputFormat|getContentType= {text/xml} OMOutputFormat [ mimeBoundary =null rootContentId=null doOptimize=false doingSWA=false isSOAP11=true charSetEncoding=UTF-8 xmlVersion=null contentType=text/xml ignoreXmlDeclaration=false autoCloseWriter=false actionProperty=null optimizedThreshold=0] 
2015-09-28 11:20:32,741|MTOMXMLStreamWriter|Creating MTOMXMLStreamWriter 
2015-09-28 11:20:32,741|MTOMXMLStreamWriter|OutputStream =class org.springframework.ws.transport.AbstractSenderConnection$RequestTransportOutputStream 
2015-09-28 11:20:32,741|MTOMXMLStreamWriter|OMFormat = OMOutputFormat [ mimeBoundary =null rootContentId=null doOptimize=false doingSWA=false isSOAP11=true charSetEncoding=UTF-8 xmlVersion=null contentType=text/xml ignoreXmlDeclaration=false autoCloseWriter=false actionProperty=null optimizedThreshold=0] 
2015-09-28 11:20:32,741|MTOMXMLStreamWriter|preserveAttachments = false 
2015-09-28 11:20:32,741|StAXUtils|XMLStreamWriter is org.apache.axiom.util.stax.dialect.Woodstox4StreamWriterWrapper 
2015-09-28 11:20:32,741|OMDataSourceExtBase|serialize [email protected] 
2015-09-28 11:20:32,741|MTOMXMLStreamWriter|Returning access to the original output stream: org.springframework.ws.[email protected]50f9c7a0 
2015-09-28 11:20:32,741|MTOMXMLStreamWriter|Calling MTOMXMLStreamWriter.flush 
2015-09-28 11:20:32,788|OMDataSourceExtBase|serialize OutputStream optimisation: true 
2015-09-28 11:20:32,788|OMDataSourceExtBase|serialize output=org.springframework.ws.[email protected]50f9c7a0 format=OMOutputFormat [ mimeBoundary =null rootContentId=null doOptimize=false doingSWA=false isSOAP11=true charSetEncoding=UTF-8 xmlVersion=null contentType=null ignoreXmlDeclaration=false autoCloseWriter=false actionProperty=null optimizedThreshold=0] 
2015-09-28 11:20:32,788|ByteArrayDataSource|getXMLBytes encoding=UTF-8 
2015-09-28 11:20:32,788|SOAPEnvelopeImpl|Could not close builder or parser due to: 
2015-09-28 11:20:32,788|SOAPEnvelopeImpl|builder is null 
2015-09-28 11:20:32,788|MTOMXMLStreamWriter|Calling MTOMXMLStreamWriter.flush 
2015-09-28 11:20:32,788|MTOMXMLStreamWriter|close 
***** 
HERE IT STOPS WHILE TRANSFERRING THE DOC OVER NETWORK 
***** 
2015-09-28 11:20:38,322|MIMEMessage|Attachments contentLength=0, contentTypeString=Multipart/Related; start-info="text/xml"; type="application/xop+xml"; boundary="----=_Part_434_1482047736.1443432076967" 
2015-09-28 11:20:38,342|MIMEMessage|getRootPartContentID rootContentID=null 
2015-09-28 11:20:38,342|MIMEMessage|readHeaders 
2015-09-28 11:20:38,342|MIMEMessage|addHeader: (Content-Type) value=(application/xop+xml; charset=utf-8; type="text/xml") 
2015-09-28 11:20:38,342|PartImpl|getHeader name=(content-id) value=(null) 
2015-09-28 11:20:38,358|MIMEMessage|getRootPartContentID rootContentID=null 
2015-09-28 11:20:38,358|PartImpl|Using blob of type org.apache.axiom.blob.MemoryBlobImpl 
2015-09-28 11:20:38,358|PartImpl|getHeader name=(Content-Transfer-Encoding) value=(null) 
2015-09-28 11:20:38,358|DebugInputStream|EOF reached after reading 516 bytes in 1 chunks 
2015-09-28 11:20:38,358|MIMEMessage|getRootPartContentID rootContentID=null 
2015-09-28 11:20:38,358|PartImpl|getHeader name=(content-type) value=(application/xop+xml; charset=utf-8; type="text/xml") 
2015-09-28 11:20:38,389|DefaultOMMetaFactoryLocator|Starting class path based discovery 
2015-09-28 11:20:38,389|ImplementationFactory|Loading jar:file:/C:/Users/Max/.m2/repository/org/apache/ws/commons/axiom/axiom-impl/1.2.15/axiom-impl-1.2.15.jar!/META-INF/axiom.xml 
2015-09-28 11:20:38,389|ImplementationFactory|Discovered implementations: [llom(metaFactory=org.apache.axiom.om.impl.llom.factory.OMLinkedListMetaFactory,features=[default(priority=100)])] 
2015-09-28 11:20:38,405|PriorityBasedOMMetaFactoryLocator|Meta factories: 
    default: org.apache.axiom.om.impl.llom.factory.OMLinkedListMetaFactory 
    2015-09-28 11:20:38,405|StAXSOAPModelBuilder|Starting to process SOAP 1.1 message 
2015-09-28 11:20:38,405|WebServiceTemplate|Received response [AxiomSoapMessage] for request [AxiomSoapMessage] 
2015-09-28 11:20:38,405|PullSerializer|Pull serializer created; initial state is [email protected]98[cache=false,document=false] 
2015-09-28 11:20:38,421|StAXBuilder|Caching disabled; current element level is 3 
2015-09-28 11:20:38,421|Navigator|Switching to pull-through mode; first event is START_ELEMENT; depth is 1 
2015-09-28 11:20:38,421|PullSerializer|Switching to state org[email protected]35c7d3d3[[email protected]23dd3a] 
2015-09-28 11:20:38,421|XOPDecodingStreamReader|processXopInclude - found href : cid:e8e49803-f357-4757-bcde-6c99abb48cf4%40ws.xxxx.com 
2015-09-28 11:20:38,421|XOPDecodingStreamReader|processXopInclude - decoded contentID : [email protected] 
2015-09-28 11:20:38,421|XOPDecodingStreamReader|Encountered xop:Include for content ID '[email protected]' 
2015-09-28 11:20:38,421|MIMEMessage|readHeaders 
2015-09-28 11:20:38,421|MIMEMessage|addHeader: (Content-Type) value=(application/octet-stream) 
2015-09-28 11:20:38,421|MIMEMessage|addHeader: (Content-ID) value=(<[email protected]>) 
2015-09-28 11:20:38,421|MIMEMessage|addHeader: (Content-Transfer-Encoding) value=(binary) 
2015-09-28 11:20:38,421|PartImpl|getHeader name=(content-id) value=(<[email protected]>) 
2015-09-28 11:20:38,421|PartImpl|Using blob of type org.apache.axiom.blob.MemoryBlobImpl 
2015-09-28 11:20:38,421|PartImpl|getHeader name=(Content-Transfer-Encoding) value=(binary) 
2015-09-28 11:20:38,499|DebugInputStream|EOF reached after reading 64541873 bytes in 15938 chunks 
2015-09-28 11:20:39,499|PullSerializer|Restoring state [email protected]98[cache=false,document=false] 
2015-09-28 11:20:39,499|StAXBuilder|Caching re-enabled; new element level: 2; done=false 
2015-09-28 11:20:39,500|PullSerializer|Switching to state o[email protected]1e229be 
2015-09-28 11:20:39,501|AbstractReplyProducingMessageHandler|handler 'org.springframework.integration.ws.MarshallingWebServiceOutboundGateway#1' sending reply Message: [[email protected]][Headers={timestamp=1443432039501, id=d9ffd3d4-48f3-504e-00a1-9ccd5d1d56e8, errorChannel=org.springfra[email protected]15160f3c, replyChannel=org.springfra[email protected]15160f3c, useStub=false}] 
2015-09-28 11:20:39,501|AbstractMessageChannel$ChannelInterceptorList|preSend on channel 'singleFileRespChannel', message: [[email protected]][Headers={timestamp=1443432039501, id=d9ffd3d4-48f3-504e-00a1-9ccd5d1d56e8, errorChannel=org.springfra[email protected]15160f3c, replyChannel=org.springfra[email protected]15160f3c, useStub=false}] 
2015-09-28 11:20:39,501|AbstractMessageHandler|[email protected] received message: [[email protected]][Headers={timestamp=1443432039501, id=d9ffd3d4-48f3-504e-00a1-9ccd5d1d56e8, errorChannel=org.springfra[email protected]15160f3c, replyChannel=org.springframework.integration[email protected], useStub=false}] 
2015-09-28 11:20:39,501|AbstractReplyProducingMessageHandler|handler '[email protected]' sending reply Message: [[email protected]][Headers={timestamp=1443432039501, id=d9ffd3d4-48f3-504e-00a1-9ccd5d1d56e8, errorChannel=org.springfra[email protected]15160f3c, replyChannel=org.springfra[email protected]15160f3c, useStub=false}] 
2015-09-28 11:20:39,501|AbstractMessageChannel$ChannelInterceptorList|postSend (sent=true) on channel 'singleFileRespChannel', message: [[email protected]][Headers={timestamp=1443432039501, id=d9ffd3d4-48f3-504e-00a1-9ccd5d1d56e8, errorChannel=org.springfra[email protected]15160f3c, replyChannel=org.springfra[email protected]15160f3c, useStub=false}] 
2015-09-28 11:20:39,501|AbstractMessageChannel$ChannelInterceptorList|postSend (sent=true) on channel 'singleFileReqChannel', message: [[email protected]][Headers={timestamp=1443432032632, id=0ce05572-05f6-5e5e-e819-63377ba4e0b1, errorChannel=org.springfra[email protected]15160f3c, replyChannel=org.springfra[email protected]15160f3c}] 
2015-09-28 11:20:39,501|IntegrationObjectSupport|Unable to attempt conversion of Message payload types. Component 'filewsEntry' has no explicit ConversionService reference, and there is no 'integrationConversionService' bean within the context. 
**** 
HERE THE SERVICE GATEWAY RETURNS THE CONTROL TO MY JAVA CODE 
**** 
2015-09-28 11:20:39,501|TestFileWsInvocation|SINGLEFILE STREAM: "myFile" 
2015-09-28 11:20:39,501|TestFileWsInvocation|writing the stream 
2015-09-28 11:20:39,501|TestFileWsInvocation|just read 1024 Bytes from file : "1234567.......... " 

с ИСПОЛЬЗОВАНИЕМ SAAJ тот же:

2015-09-28 11:52:28,760|WebServiceAccessor|Opening [[email protected]] to [http://xxxx:8080/filestreamer/ws/] 
2015-09-28 11:52:28,791|AbstractHeaderMapper|headerName=[useStub] WILL NOT be mapped 
2015-09-28 11:52:28,807|WebServiceTemplate|Sent request [SaajSoapMessage {http://ws.xxxx.com/filestreamer}fileRequest] 
****** 
STOPS WHILE GETTING ALL THE FILE 
****** 
2015-09-28 11:52:34,948|WebServiceTemplate|Received response [SaajSoapMessage {http://ws.xxxx.com/filestreamer}fileResponse] for request [SaajSoapMessage {http://ws.xxxx.com/filestreamer}fileRequest] 
2015-09-28 11:52:35,371|AbstractReplyProducingMessageHandler|handler 'org.springframework.integration.ws.MarshallingWebServiceOutboundGateway#1' sending reply Message: [[email protected]][Headers={timestamp=1443433955371, id=0a41ab57-dac8-6f7e-3ad9-c71a745f5b0a, errorChannel=org.springfra[email protected]78561bc6, replyChannel=org.springfra[email protected]78561bc6, useStub=false}] 
2015-09-28 11:52:35,371|AbstractMessageChannel$ChannelInterceptorList|preSend on channel 'singleFileRespChannel', message: [[email protected]][Headers={timestamp=1443433955371, id=0a41ab57-dac8-6f7e-3ad9-c71a745f5b0a, errorChannel=org.springfra[email protected]78561bc6, replyChannel=org.springfra[email protected]78561bc6, useStub=false}] 
2015-09-28 11:52:35,371|AbstractMessageHandler|[email protected] received message: [[email protected]][Headers={timestamp=1443433955371, id=0a41ab57-dac8-6f7e-3ad9-c71a745f5b0a, errorChannel=org.springframework.integra[email protected], replyChannel=org.springfra[email protected]78561bc6, useStub=false}] 
2015-09-28 11:52:35,371|AbstractReplyProducingMessageHandler|handler '[email protected]' sending reply Message: [[email protected]][Headers={timestamp=1443433955371, id=0a41ab57-dac8-6f7e-3ad9-c71a745f5b0a, errorChannel=org.springfra[email protected]78561bc6, replyChannel=org.springfra[email protected]78561bc6, useStub=false}] 
2015-09-28 11:52:35,371|AbstractMessageChannel$ChannelInterceptorList|postSend (sent=true) on channel 'singleFileRespChannel', message: [[email protected]][Headers={timestamp=1443433955371, id=0a41ab57-dac8-6f7e-3ad9-c71a745f5b0a, errorChannel=org.springfra[email protected]78561bc6, replyChannel=org.springfra[email protected]78561bc6, useStub=false}] 
2015-09-28 11:52:35,371|AbstractMessageChannel$ChannelInterceptorList|postSend (sent=true) on channel 'singleFileWSReqChannel', message: [[email protected]][Headers={timestamp=1443433948760, id=42d187e8-c0c6-4077-1000-8840e2c531ba, errorChannel=org.springfra[email protected]78561bc6, replyChannel=org.springfra[email protected]78561bc6, useStub=false}] 
2015-09-28 11:52:35,371|AbstractMessageChannel$ChannelInterceptorList|postSend (sent=true) on channel 'singleFileRouterChannel', message: [[email protected]][Headers={timestamp=1443433948760, id=42d187e8-c0c6-4077-1000-8840e2c531ba, errorChannel=org.springfra[email protected]78561bc6, replyChannel=org.springfra[email protected]78561bc6, useStub=false}] 
2015-09-28 11:52:35,371|AbstractMessageChannel$ChannelInterceptorList|postSend (sent=true) on channel 'singleFileReqChannel', message: [[email protected]][Headers={timestamp=1443433948760, id=6ebcc8b3-0db4-1e67-9619-98716ff362ff, errorChannel=org.springfra[email protected]78561bc6, replyChannel=org.springfra[email protected]78561bc6}] 
2015-09-28 11:52:35,371|IntegrationObjectSupport|Unable to attempt conversion of Message payload types. Component 'filewsEntry' has no explicit ConversionService reference, and there is no 'integrationConversionService' bean within the context. 
2015-09-28 11:52:35,371|TestFileWsInvocation|SINGLEFILE STREAM: 0 
2015-09-28 11:52:35,371|TestFileWsInvocation|writing the stream 
2015-09-28 11:52:35,371|TestFileWsInvocation|just read 1024 Bytes from file : "12345........" 
+0

Пожалуйста, поделитесь вам ответ XML и его JAXB представлением. Как выглядит процесс вашего файла? Я имею в виду взаимодействие с этим шлюзом 'filewsEntry'. –

+0

'Но S.I. сохраняет файлы в памяти при передаче:' ins't аргумент стороне SI. Возможно, это ответственность Spring WS или даже транспорта, который вы используете ... –

+0

Привет, ребята, спасибо ... Я добавляю информацию к сообщению. – MaxS

ответ

1

Проблема с SAAJ заключается в том, что ее API не предназначен для поддержки потоковой передачи вложений. Apache Аксиома с другой стороны, предназначена для поддержки, но есть недостаток дизайна в Spring-WS, что предотвращает его используя возможности Axiom в:

http://veithen.github.io/2015/10/05/spring-ws-mtom.html

+0

Привет, Андреас, спасибо. Я отлаживал дальше, и я узнал, что передача «всего файла» происходит именно при вызове getWebServiceTemplate(). MarshalSendAndReceive (req); использует HttpURLConnection, что в методе hasResponse (из абстрактного класса) копируется все в байт [], чтобы вернуть true. Кажется, моя проблема срабатывает даже перед немаршаллирующей частью. Я думал, что это может быть связано с http-chunking, но я вижу заголовок с кодировкой chunked в HTTP raw req. С вашего поста я предполагаю, что, даже если я преодолею эту проблему, я найду другие проблемы позже, как указано в вашем блоге. – MaxS

+0

На самом деле есть две дополнительные проблемы, которые возникают только на стороне клиента. Я обновил свой пост в блоге. –

+0

Спасибо, хорошо, я приму ваш ответ, так как ваше сообщение в блоге будет полным и точным. Надеюсь, они решат эти проблемы. Было бы лучше поставить ответ (или повторить его) здесь, в ответ, чтобы не вводить внешнюю зависимость (на всякий случай сообщение в блоге будет удалено или перенесено в другое место) Спасибо вам. – MaxS