2013-10-02 4 views
3

이상한 문제가있어 바닥을 차지할 수 없습니다. 기본적으로 비누 XML을 webservice에 보내고 (소비자) 수신해야합니다. 이 문제에 대한 올바른 접근 방법은 Apache가 제공 한 즉시 사용할 수있는 인터셉터를 사용하는 것입니다. 이것들은 잘 작동하지만 메서드가 대량의 매개 변수/개체를 받아들이고 큰 비누 요청/응답 xml을 생성하는 많은 양의 매개 변수/개체를 반환하는 특별한 경우가 있습니다.JaxWSClient에서 LoggingInInceptceptor를 활성화 할 때 "스트림이 닫혔습니다."라는 오류가 발생했습니다.

응용 프로그램 구성

봄 설정 :

<jaxws:client id="serviceClient" 
       serviceClass="com.services.stubs.ServiceAPI" 
       address="${service.url}"> 
    <jaxws:inInterceptors> 
     <ref bean="incomingInterceptor"/> 
    </jaxws:inInterceptors> 
    <jaxws:outInterceptors> 
     <ref bean="outgoingInterceptor"/> 
    </jaxws:outInterceptors> 
</jaxws:client> 

내 인터셉터 클래스 :

public class OutLoggingInterceptor extends LoggingOutInterceptor 
{ 
    public OutLoggingInterceptor() 
    { 
     super(Phase.PRE_STREAM); 
    } 
} 


public class InLoggingInterceptor extends LoggingInInterceptor 
{ 
    public InLoggingInterceptor() 
    { 
     super(Phase.RECEIVE); 
    } 
} 

오류 아래의 오류가 발생되고있다 그러나 SOAP 요청/응답은 항상 제대로 인쇄되고있다 던지기 :

org.apache.cxf.interceptor.Fault: stream is closed 
    at org.apache.cxf.interceptor.LoggingInInterceptor.logging(LoggingInInterceptor.java:167) ~[cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.interceptor.LoggingInInterceptor.handleMessage(LoggingInInterceptor.java:78) ~[cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271) [cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:811) [cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1590) [cxf-rt-transports-http-2.7.6.jar:2.7.6] 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1486) [cxf-rt-transports-http-2.7.6.jar:2.7.6] 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1305) [cxf-rt-transports-http-2.7.6.jar:2.7.6] 
    at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:50) [cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:223) [cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) [cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:623) [cxf-rt-transports-http-2.7.6.jar:2.7.6] 
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) [cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271) [cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:541) [cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474) [cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377) [cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330) [cxf-api-2.7.6.jar:2.7.6] 
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) [cxf-rt-frontend-simple-2.7.6.jar:2.7.6] 
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134) [cxf-rt-frontend-jaxws-2.7.6.jar:2.7.6] 
+0

AbstractSoapInterceptor를 사용해 보셨나요? –

답변

0

몇 가지 해결책을 제안 할 수 있습니다. 그들 중 누구도 당신을 위해 일했는지 알려주십시오.

1) LoggingOutInterceptor에서 서브 클래 싱하는 이유는 무엇입니까? 당신이 필요로하는 것이 있다면 그것이 추가되는 단계를 지정하는 것입니다. Spring 컨텍스트 설정에서 적절한 생성자를 사용하십시오.

2) Apache CXF를 사용하여 SOAP 서비스를 구현할 때 비슷한 오류가 발생했습니다. A는 인터셉터 체인에서 2 개의 사용자 지정 인터셉터를가집니다. 그 중 하나는 메시지의 입력 스트림을 읽음으로써 일부 사용자 지정 작업을 수행하는 것입니다. 문제는 Xerces가 구문 분석 후에 입력 스트림을 닫아서 다른 인터셉터가 이미 닫힌 입력 스트림을 얻고 있다는 것이 었습니다.

나를 위해 유일한 해결책은 this 솔루션을 사용하여 입력 스트림을 복제하는 것이 었습니다. 같은

뭔가 :

// Exception handling ommitted 

InputStream originalStream = soapMessage.getContent(InputStream.class); 

// Reading contents of original stream into memory 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
byte[] buffer = new byte[1024]; 
int len; 
while ((len = originalStream.read(buffer)) > -1) { 
    baos.write(buffer, 0, len); 
} 
baos.flush(); 
baos.close(); 

// Open new InputStreams using the recorded bytes 
InputStream streamForThisInterceptor = new ByteArrayInputStream(baos.toByteArray()); 
InputStream streamForOtherInterceptors = new ByteArrayInputStream(baos.toByteArray()); 

// Replacing stream for other interceptors 
soapMessage.setContent(InputStream.class, streamForOtherInterceptors); 

끔찍한 솔루션은,하지만 일을하는 유일한 하나입니다.

3) 아파치 commons-io의 CloseShieldInputStream을 사용해 볼 수도 있습니다. 운이 더 좋을 수도 있습니다.

관련 문제