2013-04-12 2 views
1

IBM WebSphere 7 및 8 내의 JAXWS 구현은 비누 핸들러 및 대형 MTOM 부착물과 관련하여 몇 가지 문제가있는 것으로 보입니다. SOAPMessageContext 객체에서 getMessage()가 호출 될 때 모든 첨부 파일 바이너리 내용을 포함한 전체 메시지가 메모리로 읽혀지는 것으로 보입니다. 이로 인해 JVM에서 사용 가능한 메모리가 부족해질 수 있습니다. 들어오는 요청 첨부은 JVM에서 사용 가능한 메모리의 양보다 큰 경우 상기 코드에서 JAXWS 비누 핸들러 대형 MTOM 부착물

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

    ... 
} 

는 context.getMessage()는 메모리 예외에서 초래할 수있다.

이 원치 않는 기능을 트리거하지 않고 SoapHeader 요소에 액세스하려면 어떻게해야합니까? SOAPMessageContext 클래스에는 getHeaders (...) 메소드가 있지만 정확히 어떻게 사용하는지 모르겠습니다. JAXBContext를 위해 무엇을 전달해야하는지 구체적으로 알지 못합니다. 아무도 예제 나 설명을 제공 할 수 있습니까?

는 여기에 또 다른 관련 유래 기사입니다 : JAX-WS SoapHandler with large messages: OutOfMemoryError

답변

0
여기

은 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; 
+0

Apache CXF 런타임을 사용하여이 작업을 수행하는 방법과 관련하여이 동일한 스택 스레드에 대해 별도의 답변을 게시했습니다. – Kabron

0

아파치 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")