JAXWS Soap Handler Large MTOM Attachments

血红的双手。 提交于 2020-01-10 05:51:07

问题


The JAXWS implementation within IBM WebSphere 7 and 8 appears to have some problems when it comes to soap handlers and large MTOM attachments. It appears that the entire message, including all attachment binary content, is read into memory when getMessage() is invoked on the SOAPMessageContext object. This can very easily cause the JVM to run out of available memory.

@Override
public boolean handleMessage(SOAPMessageContext context) {
    SOAPMessage soapMsg = context.getMessage();

    ...
}

In the above code snippet, context.getMessage() can result in out of memory exceptions if the incoming request attachments are larger than the amount of free memory available in the JVM.

How can I get access to the SoapHeader elements without triggering this undesired functionality? I see that the SOAPMessageContext class has a getHeaders(...) method but I'm not sure how to use it exactly. I'm specifically unsure what to pass in for the JAXBContext. Can anybody provide an example or explanation how to use this method?

Here's another related stackoverflow article : JAX-WS SoapHandler with large messages: OutOfMemoryError


回答1:


Here is how to access the headers without reading the entire message using the WebSphere built-in JAX-WS implementation.

public boolean handleMessage(SOAPMessageContext context) {

    AttributedURI messageIdURI = (AttributedURI)context.get("com.ibm.wsspi.wsaddressing.inbound.MessageID");
    String messageId = "";
    if (messageIdURI != null && messageIdURI.getURI() != null) {
        messageId = messageIdURI.getURI().toString();
    }
    EndpointReference fromApplicationEPR = (EndpointReference)context.get("com.ibm.wsspi.wsaddressing.inbound.FromEPR");
    String fromApplication = "";
    if (fromApplicationEPR != null && fromApplicationEPR.getAddress() != null &&
        fromApplicationEPR.getAddress().getURI() != null) {
        fromApplication = fromApplicationEPR.getAddress().getURI().toString();
    }

    ...

    return true;
}

Note that this differs based on the precise JAX-WS implementation. I'll post how to do this via Apache CXF when I get a chance. Here are the needed imports for the above code:

import com.ibm.ws.wsaddressing.AttributedURI;
import com.ibm.ws.wsaddressing.EndpointReference;



回答2:


For Apache CXF, the best approach is to use an Interceptor which is CXF implementation specific. Below is an example custom interceptor class.

package com.company.app.interceptor;

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.apache.log4j.Logger;
import org.w3c.dom.Element;

public class SOAPHeaderInterceptor extends AbstractSoapInterceptor  {
    private static Logger logger = Logger.getLogger(SOAPHeaderInterceptor.class);

    public SOAPHeaderInterceptor() {
        super(Phase.USER_PROTOCOL);
    }

    @Override
    public void handleMessage(SoapMessage message) throws Fault {
        try {
            Header fromHeader = message.getHeader(new QName("http://www.w3.org/2005/08/addressing", "From"));
            Header messageIdHeader = message.getHeader(new QName("http://www.w3.org/2005/08/addressing", "MessageID"));

            String from = null;
            if (fromHeader != null && fromHeader.getObject() != null) {
                from = ((Element)fromHeader.getObject()).getTextContent();
            }
            String messageId = null; 
            if (messageIdHeader != null && messageIdHeader.getObject() != null) {
                messageId = ((Element)messageIdHeader.getObject()).getTextContent();
            }
        } catch (Exception e) {
            logger.error("Unable to read SOAP Headers", e);
        } 
    }
}

Then, in your JAX-WS service implementation class specify the @InInterceptors annotation.

@InInterceptors(interceptors ="com.company.app.interceptor.SOAPHeaderInterceptor")


来源:https://stackoverflow.com/questions/15979580/jaxws-soap-handler-large-mtom-attachments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!