2016-06-22 86 views
0

我们正在使用最新版本的Apache CXF 3.1.6,我在代码中发现了一个有趣的情况。如何处理Out Out Interceptor中的运行时异常,Apache CXF

假设我们有一个叫做InterceptorA拦截器,在这里,我们希望它触发正常和错误输出,所以我们在这两个注册吧:

  • OutInterceptors
  • OutFaultInterceptors

有趣的开始时InterceptorA调用服务,其中抛出RuntimeException

  1. 如果发生这种情况在正常的,出拦截链中,InterceptorA会被调用两次!因为当RuntimeException被抛出。我们进入出故障链,再次调用InterceptorA,然后再次拨打服务和...

  2. 不可避免的是,我们得到一个RuntimeException故障链。现在,由于我不明白的原因,CXF返回一个空信息和HTTP 200

所以...

对于双通话的问题,我想在Message一个简单的标志,说明如果InterceptorA是以前调用。如果不是,我们可以做正规的。但问题仍然是,当我们在出现故障链和RuntimeException发生。

为什么结果200 OK?为什么身体是空的?

为了使问题完整,我提出了一个来自这种情况的日志。我加快了这个过程。首先我们可以看到Fault: Service error这是一个RuntimeException我已经强制服务了。我们输入输出故障链,然后我丢RuntimeException: Interceptor error。 我可以观察到的下一件事是SoapUI中的空响应。

16-06-22 19:12:36 [W] [LogUtils.java:449] Application {http://domain.com/service/}EEMediationServiceImplService#{http://domain.com/service/}transfer has thrown exception, unwinding now 
org.apache.cxf.interceptor.Fault: Service error 
    at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:162) ~[cxf-core-3.1.6.jar:3.1.6] 
    at org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.createFault(AbstractJAXWSMethodInvoker.java:267) ~[cxf-rt-frontend-jaxws-3.1.6.jar:3.1.6] 
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:128) ~[cxf-core-3.1.6.jar:3.1.6] 
    at org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.invoke(AbstractJAXWSMethodInvoker.java:232) ~[cxf-rt-frontend-jaxws-3.1.6.jar:3.1.6] 
    at org.apache.cxf.jaxws.JAXWSMethodInvoker.invoke(JAXWSMethodInvoker.java:85) ~[cxf-rt-frontend-jaxws-3.1.6.jar:3.1.6] 
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:74) ~[cxf-core-3.1.6.jar:3.1.6] 
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) ~[cxf-core-3.1.6.jar:3.1.6] 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_91] 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_91] 
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor$2.run(ServiceInvokerInterceptor.java:126) ~[cxf-core-3.1.6.jar:3.1.6] 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_91] 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_91] 
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91] 
Caused by: java.lang.RuntimeException: Service error 
    at pl.ds.eemediation.service.INServiceStub.transfer(INServiceStub.java:64) ~[classes/:na] 
    at pl.ds.eemediation.service.EEMediationServiceImpl.transfer(EEMediationServiceImpl.java:102) ~[classes/:na] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91] 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_91] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91] 
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91] 
    at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180) ~[cxf-core-3.1.6.jar:3.1.6] 
    at org.apache.cxf.jaxws.JAXWSMethodInvoker.performInvocation(JAXWSMethodInvoker.java:66) ~[cxf-rt-frontend-jaxws-3.1.6.jar:3.1.6] 
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) ~[cxf-core-3.1.6.jar:3.1.6] 
    ... 10 common frames omitted 
16-06-22 19:12:36 [W] [LogUtils.java:449] Application {http://domain.com/service/}EEMediationServiceImplService#{http://domain.com/service/}transfer has thrown exception, unwinding now 
java.lang.RuntimeException: Interceptor error 
    at pl.ds.eemediation.antifraud.interceptors.AntifraudInterceptor.handleMessage(AntifraudInterceptor.java:45) ~[classes/:na] 
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) [cxf-core-3.1.6.jar:3.1.6] 
    at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:112) [cxf-core-3.1.6.jar:3.1.6] 
    at org.apache.cxf.phase.PhaseInterceptorChain.wrapExceptionAsFault(PhaseInterceptorChain.java:366) [cxf-core-3.1.6.jar:3.1.6] 
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:324) [cxf-core-3.1.6.jar:3.1.6] 
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-core-3.1.6.jar:3.1.6] 
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:254) [cxf-rt-transports-http-3.1.6.jar:3.1.6] 
    at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:234) [cxf-rt-transports-http-jetty-3.1.6.jar:3.1.6] 
    at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:70) [cxf-rt-transports-http-jetty-3.1.6.jar:3.1.6] 
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1129) [jetty-server-9.2.15.v20160210.jar:9.2.15.v20160210] 
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1065) [jetty-server-9.2.15.v20160210.jar:9.2.15.v20160210] 
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.2.15.v20160210.jar:9.2.15.v20160210] 
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215) [jetty-server-9.2.15.v20160210.jar:9.2.15.v20160210] 
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.15.v20160210.jar:9.2.15.v20160210] 
    at org.eclipse.jetty.server.Server.handle(Server.java:499) [jetty-server-9.2.15.v20160210.jar:9.2.15.v20160210] 
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) [jetty-server-9.2.15.v20160210.jar:9.2.15.v20160210] 
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) [jetty-server-9.2.15.v20160210.jar:9.2.15.v20160210] 
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) [jetty-io-9.2.15.v20160210.jar:9.2.15.v20160210] 
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) [jetty-util-9.2.15.v20160210.jar:9.2.15.v20160210] 
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) [jetty-util-9.2.15.v20160210.jar:9.2.15.v20160210] 
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91] 
16-06-22 19:12:36 [D] [HttpConnection.java:657] [email protected][PROCESSING][i=ResponseInfo{HTTP/1.1 200 null,-1,false},[email protected]] generate: NEED_HEADER (null,[p=0,l=0,c=0,r=0],false)@START 
16-06-22 19:12:36 [D] [HttpConnection.java:657] [email protected][PROCESSING][i=ResponseInfo{HTTP/1.1 200 null,-1,false},[email protected]] generate: FLUSH ([p=0,l=117,c=8192,r=117],[p=0,l=0,c=0,r=0],false)@COMMITTED 
16-06-22 19:12:36 [D] [WriteFlusher.java:295] write: [email protected]{IDLE} [[email protected][p=0,l=117,c=8192,r=117]={<<<HTTP/1.1 200 OK\r\n....v20160210)\r\n\r\n>>>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}] 
16-06-22 19:12:36 [D] [WriteFlusher.java:118] update [email protected]{WRITING}:IDLE-->WRITING 
16-06-22 19:12:36 [D] [ChannelEndPoint.java:188] flushed 117 [email protected]{/127.0.0.1:58021<->18085,Open,in,out,-,W,6543/200000,HttpConnection}{io=0,kio=0,kro=1} 
16-06-22 19:12:36 [D] [WriteFlusher.java:118] update [email protected]{IDLE}:WRITING-->IDLE 
16-06-22 19:12:36 [D] [HttpConnection.java:657] [email protected][PROCESSING][i=ResponseInfo{HTTP/1.1 200 null,-1,false},[email protected]] generate: DONE ([p=117,l=117,c=8192,r=0],[p=0,l=0,c=0,r=0],false)@COMMITTED 
16-06-22 19:12:36 [D] [Server.java:502] RESPONSE /eemediation-ws/EEMediationServicePort 200 handled=true 
16-06-22 19:12:36 [D] [HttpChannelState.java:289] [email protected]{s=DISPATCHED i=true a=null} unhandle DISPATCHED 
16-06-22 19:12:36 [D] [HttpConnection.java:657] [email protected][PROCESSING][i=null,[email protected]{null}] generate: CONTINUE (null,[p=0,l=0,c=0,r=0],true)@COMPLETING 
16-06-22 19:12:36 [D] [HttpConnection.java:657] [email protected][PROCESSING][i=null,[email protected]{null}] generate: NEED_CHUNK (null,[p=0,l=0,c=0,r=0],true)@COMPLETING 
16-06-22 19:12:36 [D] [HttpConnection.java:657] [email protected][PROCESSING][i=null,[email protected]{null}] generate: FLUSH (null,[p=0,l=0,c=0,r=0],true)@COMPLETING 
16-06-22 19:12:36 [D] [WriteFlusher.java:295] write: [email protected]{IDLE} [[email protected][p=0,l=5,c=1024,r=5]={<<<0\r\n\r\n>>>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}] 
16-06-22 19:12:36 [D] [WriteFlusher.java:118] update [email protected]{WRITING}:IDLE-->WRITING 
16-06-22 19:12:36 [D] [ChannelEndPoint.java:188] flushed 5 [email protected]{/127.0.0.1:58021<->18085,Open,in,out,-,W,3/200000,HttpConnection}{io=0,kio=0,kro=1} 
16-06-22 19:12:36 [D] [WriteFlusher.java:118] update [email protected]{IDLE}:WRITING-->IDLE 
16-06-22 19:12:36 [D] [HttpConnection.java:657] [email protected][PROCESSING][i=null,[email protected]{null}] generate: DONE (null,[p=0,l=0,c=0,r=0],true)@END 
16-06-22 19:12:36 [D] [HttpConnection.java:373] unconsumed input [email protected][FILLING,[email protected]{/127.0.0.1:58021<->18085,Open,in,out,-,-,1/200000,HttpConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=CONTENT,877 of 877},g=HttpGenerator{s=END},[email protected]{r=1,c=true,a=COMPLETED,uri=/eemediation-ws/EEMediationServicePort}] 
16-06-22 19:12:36 [D] [HttpParser.java:1232] parseNext s=CONTENT [email protected][p=1229,l=1229,c=8192,r=0]={POST /eemediation...apenv:Envelope><<<>>>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00} 
16-06-22 19:12:36 [D] [HttpParser.java:1587] CONTENT --> END 
16-06-22 19:12:36 [D] [HttpChannel.java:705] [email protected]{r=1,c=true,a=COMPLETED,uri=/eemediation-ws/EEMediationServicePort} messageComplete 
16-06-22 19:12:36 [D] [HttpInput.java:272] [email protected] EOF 
16-06-22 19:12:36 [D] [ChannelEndPoint.java:142] filled 0 [email protected]{/127.0.0.1:58021<->18085,Open,in,out,-,-,2/200000,HttpConnection}{io=0,kio=0,kro=1} 
16-06-22 19:12:36 [D] [HttpConnection.java:322] [email protected][FILLING,[email protected]{/127.0.0.1:58021<->18085,Open,in,out,-,-,3/200000,HttpConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=END,877 of 877},g=HttpGenerator{s=END},[email protected]{r=1,c=true,a=COMPLETED,uri=/eemediation-ws/EEMediationServicePort}] filled 0 
16-06-22 19:12:36 [D] [HttpInput.java:151] [email protected] eof EOF 
16-06-22 19:12:36 [D] [HttpParser.java:1563] reset HttpParser{s=END,877 of 877} 
16-06-22 19:12:36 [D] [HttpParser.java:1587] END --> START 
16-06-22 19:12:36 [D] [HttpChannel.java:448] [email protected]{r=1,c=false,a=IDLE,uri=} handle exit, result COMPLETE 
16-06-22 19:12:36 [D] [ChannelEndPoint.java:142] filled 0 [email protected]{/127.0.0.1:58021<->18085,Open,in,out,-,-,6/200000,HttpConnection}{io=0,kio=0,kro=1} 
16-06-22 19:12:36 [D] [ChannelEndPoint.java:142] filled 0 [email protected]{/127.0.0.1:58021<->18085,Open,in,out,-,-,6/200000,HttpConnection}{io=0,kio=0,kro=1} 
16-06-22 19:12:36 [D] [HttpParser.java:1232] parseNext s=START [email protected][p=0,l=0,c=8192,r=0]={<<<>>>HTTP/1.1 200 OK\r\n...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00} 
16-06-22 19:12:36 [D] [AbstractConnection.java:128] fillInterested [email protected][FILLING,[email protected]{/127.0.0.1:58021<->18085,Open,in,out,-,-,7/200000,HttpConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of -1},g=HttpGenerator{s=START},[email protected]{r=1,c=false,a=IDLE,uri=}] 
16-06-22 19:12:36 [D] [AbstractConnection.java:275] FILLING-->FILLING_FILL_INTERESTED [email protected][FILLING_FILL_INTERESTED,[email protected]{/127.0.0.1:58021<->18085,Open,in,out,-,-,7/200000,HttpConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of -1},g=HttpGenerator{s=START},[email protected]{r=1,c=false,a=IDLE,uri=}] 
16-06-22 19:12:36 [D] [AbstractConnection.java:275] FILLING_FILL_INTERESTED-->FILL_INTERESTED [email protected][FILL_INTERESTED,[email protected]{/127.0.0.1:58021<->18085,Open,in,out,-,-,8/200000,HttpConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of -1},g=HttpGenerator{s=START},[email protected]{r=1,c=false,a=IDLE,uri=}] 
16-06-22 19:12:36 [D] [SelectChannelEndPoint.java:136] Local interests updating 0 -> 1 for [email protected]{/127.0.0.1:58021<->18085,Open,in,out,R,-,0/200000,HttpConnection}{io=1,kio=0,kro=1} 
16-06-22 19:12:36 [D] [SelectorManager.java:480] Queued change [email protected] 
16-06-22 19:12:36 [D] [SelectorManager.java:602] Selector loop woken up from select, 0/1 selected 
16-06-22 19:12:36 [D] [SelectorManager.java:525] Running change [email protected] 
16-06-22 19:12:36 [D] [SelectChannelEndPoint.java:160] Key interests updated 0 -> 1 on [email protected]{/127.0.0.1:58021<->18085,Open,in,out,R,-,2/200000,HttpConnection}{io=1,kio=1,kro=1} 
16-06-22 19:12:36 [D] [SelectorManager.java:599] Selector loop waiting on select 

回答

1

我可以通过JAX-RS和JAX-WS重现您的问题。似乎从CXF拦截器抛出的异常会转义JAX-RS/JAX-WS流,并且处理不当。在我的回复Propagate exception from CXF interceptor to exception mapper上查看客户端的类似案例。

一个RuntimeException在interceptor.handleMessage生成故障和响应代码为:

  • 200,如果你的服务方法最初返回200车身会连接导致和的SOAPFault
  • 500如果您的服务方法返回原来其他错误代码。机身拥有一个的SOAPFault

interceptor.handleFault一个RuntimeException生成故障和响应代码为: - 200,如果你的服务方法返回原来200无效的身体。收到SoapFault,但XML无效 - 200如果您的服务方法最初返回其他错误代码。空体

为什么结果200 OK?

它只能是一个错误。 对于SOAP 1.2,W3C规范指定了一个400或500的状态代码,具体取决于故障类型。见表20在http://www.w3.org/TR/soap12-part2/#tabresstatereccodes

为什么身体是空的?

身体在所有情况下都不是空的。在某些情况下,CXF 3.1.6会返回SOAP错误,而真正奇怪的是,如果服务回答了200,则将正确答案与soap错误连接起来!

在真实的反应来看看我已经完成

ID: 1 
Response-Code: 200 
Encoding: UTF-8 
Content-Type: text/xml;charset=UTF-8 
Headers: {Content-Length=[199], content-type=[text/xml;charset=UTF-8], Date=[Fri, 01 Jul 2016 06:12:40 GMT], Server=[Apache-Coyote/1.1]} 
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:testWSResponse xmlns:ns2="http://test/"><return>name123</return></ns2:testWSResponse></soap:Body></soap:Envelope> 

双呼叫到拦截器是有道理的。

1)OutInterceptor1.handleMessage() - >RuntimeException

2)OutInterceptor1.handleFault() - >调用因为handleMessage产生Fault。检查javadoc of Interceptor

空隙handleFault在其上的handleMessage已调用成功,当链条的正常执行中止出于某种原因(T消息)

要求的所有拦截器(以相反的顺序)。

3)OutFaultInterceptor2.handleMessage()这是因为OutInterceptor1产生了故障。

4)OutFaultInterceptor2.handleFault()这是因为OutFaultInterceptor2.handleMessage()产生了故障

相关问题