【问题标题】:How to catch SOAP request message in CXF with WSS4JOutInterceptor when connection fails连接失败时如何使用 WSS4JOutInterceptor 在 CXF 中捕获 SOAP 请求消息
【发布时间】:2019-05-11 14:06:15
【问题描述】:

我可以根据 this SO answer.

但是,如果服务器不可用,我会从SAAJOutInterceptor(由WSS4JOutInterceptor 添加)收到以下异常,并且不会调用 LoggingCallback,因此不会收到消息:

org.apache.cxf.binding.soap.SoapFault: Connection refused: connect
        at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:221)
        at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:174)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
        at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:531)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:440)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:355)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:313)
        at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
        at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140)
        ...
Caused by: com.ctc.wstx.exc.WstxIOException: Connection refused: connect
        at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:262)
        at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:215)
        ...
Caused by: java.net.ConnectException: Connection refused: connect
        at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
        at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.net.Socket.connect(Socket.java:589)
        at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
        at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
        at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
        at sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
        at sun.net.www.http.HttpClient.New(HttpClient.java:339)
        at sun.net.www.http.HttpClient.New(HttpClient.java:357)
        at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220)
        at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1199)
        at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
        at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984)
        at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1334)
        at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1309)
        at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:274)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1345)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1306)
        at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:307)
        at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
        at org.apache.cxf.io.AbstractThresholdOutputStream.unBuffer(AbstractThresholdOutputStream.java:89)
        at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:63)
        at org.apache.cxf.io.CacheAndWriteOutputStream.write(CacheAndWriteOutputStream.java:80)
        at org.apache.cxf.io.CacheAndWriteOutputStream.write(CacheAndWriteOutputStream.java:80)
        at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:51)
        at com.ctc.wstx.io.UTF8Writer.flush(UTF8Writer.java:100)
        at com.ctc.wstx.sw.BufferingXmlWriter.flush(BufferingXmlWriter.java:242)
        at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:260)
        ...

我需要保存请求 SOAP 消息以及 WSS4JOutInterceptor 添加的所有安全内容(证书、签名...),无论消息是否成功发送或服务器是否已启动。

【问题讨论】:

    标签: soap cxf wss4j saaj


    【解决方案1】:

    问题是您必须首先写入捕获消息的输出流并仅在 onClose 回调中写入网络连接:

    class RequestInterceptor extends AbstractPhaseInterceptor<Message> {
    
        OutputStream outputStream
        OutputStream originalOutputStream
    
        public RequestInterceptor() {
            super(Phase.PRE_STREAM);
        }
    
        @Override
        public void handleMessage(Message message) throws Fault {
            originalOutputStream = message.getContent(OutputStream.class)
            CacheAndWriteOutputStream newOutputStream = new CacheAndWriteOutputStream(outputStream)
            message.setContent(OutputStream.class, newOutputStream)
            newOutputStream.registerCallback(new CachedOutputStreamCallback() {
                void onFlush(CachedOutputStream cos) {
                }
                void onClose(CachedOutputStream cos) {
                    cos.writeCacheTo(originalOutputStream)
                    originalOutputStream.close()
                }
            })
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2012-09-15
      • 1970-01-01
      • 1970-01-01
      • 2018-11-24
      • 1970-01-01
      • 1970-01-01
      • 2016-05-28
      • 2013-12-10
      • 2013-04-16
      相关资源
      最近更新 更多