分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 技术分享

关于使用Axis2 webservice 处理Fault响应时抛org.apache.axis2.AxisFault的分析

发布时间:2023-09-06 01:22责任编辑:董明明关键词:apachewebservice

使用Axis2这个框架进行webservice协议通讯,期间出了个问题,我(CLIENT)请求后,当服务端返回符合协议的SOAP异常报文,例如<soap:fault> ...

我的程序直接抛org.apache.axis2.AxisFault异常,导致连服务端给我们的报文都没有接收成功。

--请注意,是我连报文都没有接收成功,而不是接收成功后我解析失败了。

[java] view plain copy print?
  1. try{
  2. ServiceClientserviceClient=newServiceClient();
  3. Optionsoptions=newOptions();
  4. //设置超时时间,单位毫秒
  5. options.setTimeOutInMilliSeconds(this.wsTimeOut);
  6. options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
  7. options.setTo(newEndpointReference(this.wsEndpointAddress));
  8. options.setSoapVersionURI(org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
  9. options.setAction(this.wsMethod);
  10. MessageContextrequetMessageContext=newMessageContext();
  11. SOAPEnvelopeenv=this.getRequestEnvelope();
  12. log.info("version:"+env.getVersion().getEnvelopeURI());
  13. requetMessageContext.setEnvelope(env);
  14. OperationClientopClient=serviceClient.createClient(ServiceClient.ANON_OUT_IN_OP);
  15. opClient.addMessageContext(requetMessageContext);
  16. opClient.setOptions(options);
  17. opClient.execute(true);
  18. MessageContextrspMC=opClient.getMessageContext("In");
  19. response=rspMC.getEnvelope().getBody().getFirstElement();
  20. log.info("应答报文:"+rspMC.getEnvelope());
  21. }catch(AxisFaulte){
  22. this.errRspDesc="xxxxx";
  23. log.error("soapDispatchAxisFault!");
  24. throwe;
  25. }catch(Exceptione){
  26. this.errRspDesc="xxxxxxxxxxxxx!";
  27. log.error("soapDispatchException!");
  28. throwe;
  29. }
try { ????????ServiceClient serviceClient = new ServiceClient(); ????????Options options = new Options(); ????????//设置超时时间,单位毫秒 ????????options.setTimeOutInMilliSeconds(this.wsTimeOut); ??????????options.setTransportInProtocol(Constants.TRANSPORT_HTTP); ??????????options.setTo(new EndpointReference(this.wsEndpointAddress)); ??????????options.setSoapVersionURI(org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI); ??????????options.setAction(this.wsMethod); ??????????MessageContext requetMessageContext = new MessageContext(); ??????????SOAPEnvelope env = this.getRequestEnvelope(); ??????????log.info("version : "+ env.getVersion().getEnvelopeURI()); ???????????requetMessageContext.setEnvelope(env); ???????????????????????OperationClient opClient = serviceClient.createClient(ServiceClient.ANON_OUT_IN_OP); ???????????opClient.addMessageContext(requetMessageContext); ???????????opClient.setOptions(options); ???????????opClient.execute(true); ???????????MessageContext rspMC = opClient.getMessageContext("In"); ???????????response = rspMC.getEnvelope().getBody().getFirstElement(); ????????log.info("应答报文: "+ rspMC.getEnvelope()); ?????} catch (AxisFault e) { ????????this.errRspDesc = "xxxxx"; ????????log.error("soapDispatch AxisFault!"); ????????throw e; ?????} catch (Exception e) { ????????this.errRspDesc = "xxxxxxxxxxxxx!"; ????????log.error("soapDispatch Exception!"); ????????throw e; ?????}

当执行到发送请求opClient.execute(true);

服务端成功返回格式正常的SOAP异常报文,此时程序直接抛异常,走不到下面rspMC的获取,也就拿不到响应报文。

经过一段时间的查看Axis2源码,终于找到原因。

从opClient.execute(true); 入手,可以看到

[java] view plain copy print?
  1. publicfinalvoidexecute(booleanblock)throwsAxisFault{
  2. this.sc.setLastOperationContext(this.oc);
  3. this.executeImpl(block);
  4. }
 public final void execute(boolean block) throws AxisFault { ???????this.sc.setLastOperationContext(this.oc); ???????this.executeImpl(block); ???}

再看this.executeImpl(block);

[java] view plain copy print?
  1. publicvoidexecuteImpl(booleanblock)throwsAxisFault{
  2. if(log.isDebugEnabled()){
  3. log.debug("Entry:OutInAxisOperationClient::execute,"+block);
  4. }
  5. if(this.completed){
  6. thrownewAxisFault(Messages.getMessage("mepiscomplted"));
  7. }else{
  8. ConfigurationContextcc=this.sc.getConfigurationContext();
  9. MessageContextmc=this.oc.getMessageContext("Out");
  10. if(mc==null){
  11. thrownewAxisFault(Messages.getMessage("outmsgctxnull"));
  12. }else{
  13. this.prepareMessageContext(cc,mc);
  14. if(this.options.getTransportIn()==null&&mc.getTransportIn()==null){
  15. mc.setTransportIn(ClientUtils.inferInTransport(cc.getAxisConfiguration(),this.options,mc));
  16. }elseif(mc.getTransportIn()==null){
  17. mc.setTransportIn(this.options.getTransportIn());
  18. }
  19. booleanuseAsync=false;
  20. if(!mc.getOptions().isUseSeparateListener()){
  21. BooleanreplyTo=(Boolean)mc.getProperty("UseAsyncOperations");
  22. if(log.isDebugEnabled()){
  23. log.debug("OutInAxisOperationClient:useAsyncOption"+replyTo);
  24. }
  25. if(replyTo!=null){
  26. useAsync=replyTo.booleanValue();
  27. }
  28. }
  29. EndpointReferencereplyTo1=mc.getReplyTo();
  30. if(replyTo1!=null){
  31. if(replyTo1.hasNoneAddress()){
  32. thrownewAxisFault(replyTo1.getAddress()+""+"cannotbeusedwithOutInAxisOperationClient,usereither"+"fireAndForgetorsendRobust)");
  33. }
  34. if(replyTo1.isWSAddressingAnonymous()&&replyTo1.getAllReferenceParameters()!=null){
  35. mc.setProperty("includeOptionalHeaders",Boolean.TRUE);
  36. }
  37. StringcustomReplyTo=(String)this.options.getProperty(Options.CUSTOM_REPLYTO_ADDRESS);
  38. if(!Options.CUSTOM_REPLYTO_ADDRESS_TRUE.equals(customReplyTo)&&!replyTo1.hasAnonymousAddress()){
  39. useAsync=true;
  40. }
  41. }
  42. if(!useAsync&&!mc.getOptions().isUseSeparateListener()){
  43. if(block){
  44. this.send(mc);
  45. this.completed=true;
  46. }else{
  47. this.sc.getConfigurationContext().getThreadPool().execute(newOutInAxisOperationClient.NonBlockingInvocationWorker(this.callback,mc,this.axisCallback));
  48. }
  49. }else{
  50. this.sendAsync(useAsync,mc);
  51. }
  52. }
  53. }
  54. }
 public void executeImpl(boolean block) throws AxisFault { ???????if(log.isDebugEnabled()) { ???????????log.debug("Entry: OutInAxisOperationClient::execute, " + block); ???????} ???????if(this.completed) { ???????????throw new AxisFault(Messages.getMessage("mepiscomplted")); ???????} else { ???????????ConfigurationContext cc = this.sc.getConfigurationContext(); ???????????MessageContext mc = this.oc.getMessageContext("Out"); ???????????if(mc == null) { ???????????????throw new AxisFault(Messages.getMessage("outmsgctxnull")); ???????????} else { ???????????????this.prepareMessageContext(cc, mc); ???????????????if(this.options.getTransportIn() == null && mc.getTransportIn() == null) { ???????????????????mc.setTransportIn(ClientUtils.inferInTransport(cc.getAxisConfiguration(), this.options, mc)); ???????????????} else if(mc.getTransportIn() == null) { ???????????????????mc.setTransportIn(this.options.getTransportIn()); ???????????????} ???????????????boolean useAsync = false; ???????????????if(!mc.getOptions().isUseSeparateListener()) { ???????????????????Boolean replyTo = (Boolean)mc.getProperty("UseAsyncOperations"); ???????????????????if(log.isDebugEnabled()) { ???????????????????????log.debug("OutInAxisOperationClient: useAsyncOption " + replyTo); ???????????????????} ???????????????????if(replyTo != null) { ???????????????????????useAsync = replyTo.booleanValue(); ???????????????????} ???????????????} ???????????????EndpointReference replyTo1 = mc.getReplyTo(); ???????????????if(replyTo1 != null) { ???????????????????if(replyTo1.hasNoneAddress()) { ???????????????????????throw new AxisFault(replyTo1.getAddress() + "" + " can not be used with OutInAxisOperationClient , user either " + "fireAndForget or sendRobust)"); ???????????????????} ???????????????????if(replyTo1.isWSAddressingAnonymous() && replyTo1.getAllReferenceParameters() != null) { ???????????????????????mc.setProperty("includeOptionalHeaders", Boolean.TRUE); ???????????????????} ???????????????????String customReplyTo = (String)this.options.getProperty(Options.CUSTOM_REPLYTO_ADDRESS); ???????????????????if(!Options.CUSTOM_REPLYTO_ADDRESS_TRUE.equals(customReplyTo) && !replyTo1.hasAnonymousAddress()) { ???????????????????????useAsync = true; ???????????????????} ???????????????} ???????????????if(!useAsync && !mc.getOptions().isUseSeparateListener()) { ???????????????????if(block) { ???????????????????????this.send(mc); ???????????????????????this.completed = true; ???????????????????} else { ???????????????????????this.sc.getConfigurationContext().getThreadPool().execute(new OutInAxisOperationClient.NonBlockingInvocationWorker(this.callback, mc, this.axisCallback)); ???????????????????} ???????????????} else { ???????????????????this.sendAsync(useAsync, mc); ???????????????} ???????????} ???????} ???}

进send(mc)方法

[java] view plain copy print?
  1. protectedMessageContextsend(MessageContextmsgContext)throwsAxisFault{
  2. MessageContextresponseMessageContext=msgContext.getConfigurationContext().createMessageContext();
  3. responseMessageContext.setServerSide(false);
  4. responseMessageContext.setOperationContext(msgContext.getOperationContext());
  5. responseMessageContext.setOptions(newOptions(this.options));
  6. responseMessageContext.setMessageID(msgContext.getMessageID());
  7. this.addMessageContext(responseMessageContext);
  8. responseMessageContext.setServiceContext(msgContext.getServiceContext());
  9. responseMessageContext.setAxisMessage(this.axisOp.getMessage("In"));
  10. AxisEngine.send(msgContext);
  11. responseMessageContext.setDoingREST(msgContext.isDoingREST());
  12. responseMessageContext.setProperty("TRANSPORT_HEADERS",msgContext.getProperty("TRANSPORT_HEADERS"));
  13. responseMessageContext.setProperty(HTTPConstants.MC_HTTP_STATUS_CODE,msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE));
  14. responseMessageContext.setProperty("TRANSPORT_IN",msgContext.getProperty("TRANSPORT_IN"));
  15. responseMessageContext.setTransportIn(msgContext.getTransportIn());
  16. responseMessageContext.setTransportOut(msgContext.getTransportOut());
  17. this.handleResponse(responseMessageContext);
  18. returnresponseMessageContext;
  19. }
 protected MessageContext send(MessageContext msgContext) throws AxisFault { ???????MessageContext responseMessageContext = msgContext.getConfigurationContext().createMessageContext(); ???????responseMessageContext.setServerSide(false); ???????responseMessageContext.setOperationContext(msgContext.getOperationContext()); ???????responseMessageContext.setOptions(new Options(this.options)); ???????responseMessageContext.setMessageID(msgContext.getMessageID()); ???????this.addMessageContext(responseMessageContext); ???????responseMessageContext.setServiceContext(msgContext.getServiceContext()); ???????responseMessageContext.setAxisMessage(this.axisOp.getMessage("In")); ???????AxisEngine.send(msgContext); ???????responseMessageContext.setDoingREST(msgContext.isDoingREST()); ???????responseMessageContext.setProperty("TRANSPORT_HEADERS", msgContext.getProperty("TRANSPORT_HEADERS")); ???????responseMessageContext.setProperty(HTTPConstants.MC_HTTP_STATUS_CODE, msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE)); ???????responseMessageContext.setProperty("TRANSPORT_IN", msgContext.getProperty("TRANSPORT_IN")); ???????responseMessageContext.setTransportIn(msgContext.getTransportIn()); ???????responseMessageContext.setTransportOut(msgContext.getTransportOut()); ???????this.handleResponse(responseMessageContext); ???????return responseMessageContext; ???}

这里就是发送请求并接收响应的地方 再看倒数第二行this.handleResponse(responseMessageContext);

[java] view plain copy print?
  1. protectedvoidhandleResponse(MessageContextresponseMessageContext)throwsAxisFault{
  2. responseMessageContext.setSoapAction((String)null);
  3. SOAPEnveloperesenvelope;
  4. if(responseMessageContext.getEnvelope()==null){
  5. resenvelope=TransportUtils.createSOAPMessage(responseMessageContext);
  6. if(resenvelope==null){
  7. thrownewAxisFault(Messages.getMessage("blockingInvocationExpectsResponse"));
  8. }
  9. responseMessageContext.setEnvelope(resenvelope);
  10. }
  11. resenvelope=responseMessageContext.getEnvelope();
  12. if(resenvelope!=null){
  13. AxisEngine.receive(responseMessageContext);
  14. if(responseMessageContext.getReplyTo()!=null){
  15. this.sc.setTargetEPR(responseMessageContext.getReplyTo());
  16. }
  17. resenvelope=responseMessageContext.getEnvelope();
  18. if((resenvelope.hasFault()||responseMessageContext.isProcessingFault())&&this.options.isExceptionToBeThrownOnSOAPFault()){
  19. throwUtils.getInboundFaultFromMessageContext(responseMessageContext);
  20. }
  21. }
  22. }
 ??protected void handleResponse(MessageContext responseMessageContext) throws AxisFault { ???????responseMessageContext.setSoapAction((String)null); ???????SOAPEnvelope resenvelope; ???????if(responseMessageContext.getEnvelope() == null) { ???????????resenvelope = TransportUtils.createSOAPMessage(responseMessageContext); ???????????if(resenvelope == null) { ???????????????throw new AxisFault(Messages.getMessage("blockingInvocationExpectsResponse")); ???????????} ???????????responseMessageContext.setEnvelope(resenvelope); ???????} ???????resenvelope = responseMessageContext.getEnvelope(); ???????if(resenvelope != null) { ???????????AxisEngine.receive(responseMessageContext); ???????????if(responseMessageContext.getReplyTo() != null) { ???????????????this.sc.setTargetEPR(responseMessageContext.getReplyTo()); ???????????} ???????????resenvelope = responseMessageContext.getEnvelope(); ???????????if((resenvelope.hasFault() || responseMessageContext.isProcessingFault()) && this.options.isExceptionToBeThrownOnSOAPFault()) { ???????????????throw Utils.getInboundFaultFromMessageContext(responseMessageContext); ???????????} ???????} ???}

这时,我们可以看到一个很有趣的方法, if((resenvelope.hasFault() || responseMessageContext.isProcessingFault()) 总算是跟我们的异常报文有关了。跟进去看一下

[java] view plain copy print?
  1. publicbooleanhasFault(){
  2. QNamepayloadQName=this.getPayloadQName_Optimized();
  3. if(payloadQName!=null&&"Fault".equals(payloadQName.getLocalPart())){
  4. Stringbody1=payloadQName.getNamespaceURI();
  5. return"http://schemas.xmlsoap.org/soap/envelope/".equals(body1)||"http://www.w3.org/2003/05/soap-envelope".equals(body1);
  6. }else{
  7. SOAPBodybody=this.getBody();
  8. returnbody==null?false:body.hasFault();
  9. }
  10. }
 ?public boolean hasFault() { ???????QName payloadQName = this.getPayloadQName_Optimized(); ???????if(payloadQName != null && "Fault".equals(payloadQName.getLocalPart())) { ???????????String body1 = payloadQName.getNamespaceURI(); ???????????return "http://schemas.xmlsoap.org/soap/envelope/".equals(body1) || "http://www.w3.org/2003/05/soap-envelope".equals(body1); ???????} else { ???????????SOAPBody body = this.getBody(); ???????????return body == null?false:body.hasFault(); ???????} ???}

可以看到Axis2的内部处理机制,就是一但发现响应报文有Fault节点,它就要抛异常。总算找到源头了 那要如何解决这个问题 我们可以看到 if((resenvelope.hasFault() || responseMessageContext.isProcessingFault()) && this.options.isExceptionToBeThrownOnSOAPFault()) { throw Utils.getInboundFaultFromMessageContext(responseMessageContext); } 这里还有一个判断条件, this.options.isExceptionToBeThrownOnSOAPFault() 当它为TRUE时才抛异常。 这就是options的一个参数,可配置,所以给我们的代码加上

[java] view plain copy print?
  1. options.setExceptionToBeThrownOnSOAPFault(false);
options.setExceptionToBeThrownOnSOAPFault(false);

就不抛异常了,能够正常获取并解析响应报文。 总结:一切的害怕源于对代码的神秘,未知,当你把它当成自己写的代码,去反编译,去阅读,那就不会再害怕!

关于使用Axis2 webservice 处理Fault响应时抛org.apache.axis2.AxisFault的分析

原文地址:http://www.cnblogs.com/firstdream/p/7779712.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved