1

IBM WebSphere 7 および 8 内の JAXWS 実装には、soap ハンドラーと大きな MTOM 添付ファイルに関して、いくつかの問題があるようです。SOAPMessageContext オブジェクトで getMessage() が呼び出されると、すべての添付バイナリ コンテンツを含むメッセージ全体がメモリに読み込まれるようです。これにより、JVM で使用可能なメモリが不足する可能性が非常に高くなります。

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

    ...
}

上記のコード スニペットでは、受信したリクエストの添付ファイルが JVM で使用可能な空きメモリの量よりも大きい場合、context.getMessage() によってメモリ不足の例外が発生する可能性があります。

この望ましくない機能をトリガーせずに SoapHeader 要素にアクセスするにはどうすればよいですか? SOAPMessageContext クラスに getHeaders(...) メソッドがあるようですが、正確な使い方がわかりません。JAXBContext に何を渡すかは特にわかりません。このメソッドの使用方法の例や説明を誰かが提供できますか?

関連する別のスタックオーバーフロー記事は次のとおりです: JAX-WS SoapHandler with large messages: OutOfMemoryError

4

2 に答える 2

0

Apache CXF の場合、CXF 実装固有の Interceptor を使用するのが最善の方法です。以下は、カスタム インターセプタ クラスの例です。

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")
于 2013-10-11T18:02:21.290 に答える