我们有一个我们正在增强的Java Web服务,因此客户端可以向服务器发送一些非常大的消息。为了支持这些大型附件,我们正在使用MTOM。
不幸的是,我们还将WSSE安全信息添加到SOAP标头中,这导致了与超大SOAP消息结合的问题。
我们附加WSSE安全信息的代码在SOAPHandler中,如下所示:
public void addSecurity(String username, String password, SOAPMessageContext context) throws SOAPException {
SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.getHeader();
SOAPElement security = null;
if (header == null) {
header = envelope.addHeader();
}
security = header.addChildElement("Security", "wsse", WSSE_NS_URI);
context.getMessage().saveChanges();
SOAPElement usernameToken
= security.addChildElement("UsernameToken", "wsse");
usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement usernameElement
= usernameToken.addChildElement("Username", "wsse");
usernameElement.addTextNode(username);
SOAPElement passwordElement
= usernameToken.addChildElement("Password", "wsse");
passwordElement.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
passwordElement.addTextNode(password);
}
失败发生在context.getMessage().getSOAPPart().getEnvelope()
语句中。 context.getMessage()调用似乎试图获取整个消息,并且由于消息很大,我们得到堆空间错误:
Caused by: java.lang.OutOfMemoryError: Java heap space
at com.sun.xml.internal.messaging.saaj.util.ByteOutputStream.ensureCapacity(ByteOutputStream.java:99)
at com.sun.xml.internal.messaging.saaj.util.ByteOutputStream.write(ByteOutputStream.java:106)
at org.apache.xml.serializer.WriterToUTF8Buffered.flushBuffer(WriterToUTF8Buffered.java:447)
at org.apache.xml.serializer.WriterToUTF8Buffered.write(WriterToUTF8Buffered.java:191)
at org.apache.xml.serializer.WriterToUTF8Buffered.write(WriterToUTF8Buffered.java:244)
at org.apache.xml.serializer.ToStream.characters(ToStream.java:1623)
at org.apache.xalan.transformer.TransformerIdentityImpl.characters(TransformerIdentityImpl.java:1126)
at org.apache.xml.serializer.TreeWalker.dispatachChars(TreeWalker.java:246)
at org.apache.xml.serializer.TreeWalker.startNode(TreeWalker.java:416)
at org.apache.xml.serializer.TreeWalker.traverse(TreeWalker.java:145)
at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:390)
at com.sun.xml.internal.messaging.saaj.util.transform.EfficientStreamingTransformer.transform(EfficientStreamingTransformer.java:399)
at com.sun.xml.internal.messaging.saaj.soap.impl.EnvelopeImpl.output(EnvelopeImpl.java:289)
at com.sun.xml.internal.messaging.saaj.soap.impl.EnvelopeImpl.output(EnvelopeImpl.java:302)
at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getContentAsStream(SOAPPartImpl.java:311)
at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.getHeaderBytes(MessageImpl.java:1015)
at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.saveChanges(MessageImpl.java:1166)
at com.sun.xml.internal.ws.api.message.saaj.SAAJFactory.readAsSOAPMessage(SAAJFactory.java:277)
at com.sun.xml.internal.ws.api.message.saaj.SAAJFactory.readAsSAAJ(SAAJFactory.java:197)
at com.sun.xml.internal.ws.api.message.saaj.SAAJFactory.read(SAAJFactory.java:186)
at com.sun.xml.internal.ws.message.AbstractMessageImpl.toSAAJ(AbstractMessageImpl.java:217)
at com.sun.xml.internal.ws.api.message.MessageWrapper.readAsSOAPMessage(MessageWrapper.java:156)
at com.sun.xml.internal.ws.handler.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:70)
at com.ciminc.compass.singleSignOn.basic.SsoCookieRequestAppender.addSecurity(SsoCookieRequestAppender.java:147)
理想情况下,我想将我的WSSE信息添加到SOAP标头中,而不需要引入整个多兆字节的SOAP消息。这可能吗?
如果我能提供任何其他信息以澄清,请告诉我。