JAXWS SOAP处理大型MTOM附件(JAXWS Soap Handler Large MTOM

2019-08-22 11:53发布

IBM的WebSphere 7和8次中出现的JAXWS的实现有一些问题,当涉及到SOAP处理程序和大型MTOM附件。 看来,整个消息,包括所有附件二进制内容,被读入到存储器时的getMessage()这个SOAPMessageContext对象上被调用。 这可以很容易导致JVM耗尽可用内存。

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

    ...
}

在上面的代码段中,context.getMessage()可以导致内存不足异常如果传入请求的附件比的空闲内存在JVM中可用的量。

我怎样才能在不触发这个功能不正常访问SOAPHEADER元素? 我看到这个SOAPMessageContext类有一个getHeaders(...)方法,但我不知道如何准确使用它。 我不能确定具体在什么以通为JAXBContext中。 任何人能提供一个例子或解释如何使用这种方法吗?

这里还有一个计算器相关文章: JAX-WS SoapHandler大消息:OutOfMemoryError异常

Answer 1:

下面是如何访问头,不阅读使用WebSphere内置JAX-WS实现整个消息。

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;
}

请注意,这不同于基于精确的JAX-WS实现。 我会后,当我得到一个机会,如何通过Apache CXF做到这一点。 下面是需要上面的代码进口:

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


Answer 2:

对于Apache CXF,最好的方法是使用一个拦截器是CXF实现特定的。 下面是一个例子自定义拦截器类。

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);
        } 
    }
}

然后,在您的JAX-WS服务实现类指定@InInterceptors注解。

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


文章来源: JAXWS Soap Handler Large MTOM Attachments