这似乎是一个长期存在的问题,到目前为止还没有确定的解决方案:传入的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>
我正在使用JAXB(2.2.5)进行XML数据编组,但它内联附件,因此对于处理附件的端点,我直接使用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毫无意义,而且我的代码不太灵活,无法处理未来的需求。
This thread建议欺骗拦截器使用仅包含标题的邮件副本,但我无法实现它(它已经存在了几年,API可能会被更改)。这可能会禁止使用加密和签名的消息(作为回复指出),但到目前为止并不是我的要求。 This other thread建议坚持Axiom 1.2.8,它什么也没做,并且还将Axiom工厂的validateRequest
标志设置为false
(这听起来很奇怪,因为它会禁用安全性 - 没有错误但是没有安全性,那会是什么意思呢?)。
那么,任何人都可以帮我解决这个问题吗?修复JAXB,欺骗WSS4J拦截器或其他一些解决方案?欢迎任何帮助!
谢谢!