これは長年の疑問のようで、今のところ決定的な解決策はありません。着信 MTOM メッセージが SOAP メッセージにインライン化され、メモリ使用量が原因でアプリケーションがクラッシュする状況です。
受け取るファイルが大きいため、Apache Axiom (1.2.13) を使用して Spring WS (2.1) でファイル アップロード Web サービスを作成しています。
<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="true"/>
<property name="attachmentCaching" value="true"/>
</bean>
私は XML データのマーシャリングに JAXB (2.2.5) を使用していますが、これは添付ファイルをインライン化するため、添付ファイルを処理するエンドポイントにはSoapMessage
直接使用します。私が好むものではありませんが、許容できます。ここまではこの設定で問題なく、非常に大きなファイルをアップロードできます。問題は、Apache WSS4J 1.6.6 を使用している認証も必要であることです。
<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="validationActions" value="UsernameToken"/>
<property name="securementActions" value="NoSecurity"/>
</bean>
インターセプターがメッセージの検証を行うとき、添付データをメッセージの本文にインライン化し、大量のメモリを消費しOutOfMemoryError
、適切なサイズのメッセージを生成します。
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3209) ~[na:1.6.0_14]
at java.lang.String.<init>(String.java:215) ~[na:1.6.0_14]
at com.sun.org.apache.xerces.internal.xni.XMLString.toString(XMLString.java:185) ~[na:1.6.0_14]
at com.sun.org.apache.xerces.internal.parsers.AbstractDOMParser.characters(AbstractDOMParser.java:1188) ~[na:1.6.0_14]
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:463) ~[na:1.6.0_14]
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807) ~[na:1.6.0_14]
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737) ~[na:1.6.0_14]
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107) ~[na:1.6.0_14]
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:225) ~[na:1.6.0_14]
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:283) ~[na:1.6.0_14]
at weblogic.xml.jaxp.RegistryDocumentBuilder.parse(RegistryDocumentBuilder.java:163) ~[weblogic.jar:10.3.2.0]
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:124) ~[na:1.6.0_14]
at org.springframework.ws.soap.axiom.support.AxiomUtils.toDocument(AxiomUtils.java:133) ~[spring-ws-core-2.1.0.RELEASE.jar:na]
at org.springframework.ws.soap.axiom.AxiomSoapMessage.getDocument(AxiomSoapMessage.java:201) ~[spring-ws-core-2.1.0.RELEASE.jar:na]
at org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor.validateMessage(Wss4jSecurityInterceptor.java:561) ~[spring-ws-security-2.1.0.RELEASE.jar:na]
at org.springframework.ws.soap.security.AbstractWsSecurityInterceptor.handleRequest(AbstractWsSecurityInterceptor.java:123) ~[spring-ws-security-2.1.0.RELEASE.jar:na]
at org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor.handleRequest(DelegatingSmartEndpointInterceptor.java:78) ~[spring-ws-core-2.1.0.RELEASE.jar:na]
at org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:224) ~[spring-ws-core-2.1.0.RELEASE.jar:na]
at org.springframework.ws.server.MessageDispatcher.receive(MessageDispatcher.java:173) ~[spring-ws-core-2.1.0.RELEASE.jar:na]
at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:88) ~[spring-ws-core-2.1.0.RELEASE.jar:na]
at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:59) ~[spring-ws-core-2.1.0.RELEASE.jar:na]
at org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:221) ~[spring-ws-core-2.1.0.RELEASE.jar:na]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) ~[org.springframework.web.servlet-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789) ~[org.springframework.web.servlet-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) ~[javax.servlet_1.0.0.0_2-5.jar:2.5]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) ~[javax.servlet_1.0.0.0_2-5.jar:2.5]
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227) ~[weblogic.jar:10.3.2.0]
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125) ~[weblogic.jar:10.3.2.0]
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292) ~[weblogic.jar:10.3.2.0]
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175) ~[weblogic.jar:10.3.2.0]
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3591) ~[weblogic.jar:10.3.2.0]
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321) ~[com.bea.core.weblogic.security.identity_1.1.2.0.jar:1.1.2.0]
これまでのところ、この望ましくないインライン展開を修正する方法は見つかりませんでした。ヘッダーを手動で読み取って処理したくありません。WSS4J が無意味になり、将来の要件を処理するためのコードの柔軟性が低下します。
このスレッドは、ヘッダーのみを含むメッセージのコピーを使用するようにインターセプターを騙すことを提案していますが、私はそれを実装できませんでした (これは数年前のもので、API が変更される可能性があります)。これはおそらく、暗号化され署名されたメッセージの使用を禁止するでしょう (返信が指摘しているように) が、これまでのところ、私にとっての要件ではありません。この別のスレッドは、何もしなかった Axiom 1.2.8 に固執しvalidateRequest
、Axiom ファクトリのフラグをfalse
(これはセキュリティを無効にするため、奇妙に聞こえます - エラーはありませんがセキュリティはありません。それのポイントは何でしょうか? )。
それで、誰でもこの問題の解決策を手伝ってくれますか? JAXB の修正、WSS4J インターセプターのトリック、またはその他の解決策はありますか? どんな助けでも大歓迎です!
ありがとう!