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

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

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

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

[java] view plain copy print?

  1. try {
  2. ServiceClient serviceClient = new ServiceClient();
  3. Options options = new Options();
  4. //设置超时时间,单位毫秒
  5. options.setTimeOutInMilliSeconds(this.wsTimeOut);
  6. options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
  7. options.setTo(new EndpointReference(this.wsEndpointAddress));
  8. options.setSoapVersionURI(org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
  9. options.setAction(this.wsMethod);
  10. MessageContext requetMessageContext = new MessageContext();
  11. SOAPEnvelope env = this.getRequestEnvelope();
  12. log.info("version : "+ env.getVersion().getEnvelopeURI());
  13. requetMessageContext.setEnvelope(env);
  14. OperationClient opClient = serviceClient.createClient(ServiceClient.ANON_OUT_IN_OP);
  15. opClient.addMessageContext(requetMessageContext);
  16. opClient.setOptions(options);
  17. opClient.execute(true);
  18. MessageContext rspMC = opClient.getMessageContext("In");
  19. response = rspMC.getEnvelope().getBody().getFirstElement();
  20. log.info("应答报文: "+ rspMC.getEnvelope());
  21. } catch (AxisFault e) {
  22. this.errRspDesc = "xxxxx";
  23. log.error("soapDispatch AxisFault!");
  24. throw e;
  25. } catch (Exception e) {
  26. this.errRspDesc = "xxxxxxxxxxxxx!";
  27. log.error("soapDispatch Exception!");
  28. throw e;
  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. public final void execute(boolean block) throws AxisFault {
  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. public void executeImpl(boolean block) throws AxisFault {
  2. if(log.isDebugEnabled()) {
  3. log.debug("Entry: OutInAxisOperationClient::execute, " + block);
  4. }
  5. if(this.completed) {
  6. throw new AxisFault(Messages.getMessage("mepiscomplted"));
  7. } else {
  8. ConfigurationContext cc = this.sc.getConfigurationContext();
  9. MessageContext mc = this.oc.getMessageContext("Out");
  10. if(mc == null) {
  11. throw new AxisFault(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. } else if(mc.getTransportIn() == null) {
  17. mc.setTransportIn(this.options.getTransportIn());
  18. }
  19. boolean useAsync = false;
  20. if(!mc.getOptions().isUseSeparateListener()) {
  21. Boolean replyTo = (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. EndpointReference replyTo1 = mc.getReplyTo();
  30. if(replyTo1 != null) {
  31. if(replyTo1.hasNoneAddress()) {
  32. throw new AxisFault(replyTo1.getAddress() + "" + " can not be used with OutInAxisOperationClient , user either " + "fireAndForget or sendRobust)");
  33. }
  34. if(replyTo1.isWSAddressingAnonymous() && replyTo1.getAllReferenceParameters() != null) {
  35. mc.setProperty("includeOptionalHeaders", Boolean.TRUE);
  36. }
  37. String customReplyTo = (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(new OutInAxisOperationClient.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. protected MessageContext send(MessageContext msgContext) throws AxisFault {
  2. MessageContext responseMessageContext = msgContext.getConfigurationContext().createMessageContext();
  3. responseMessageContext.setServerSide(false);
  4. responseMessageContext.setOperationContext(msgContext.getOperationContext());
  5. responseMessageContext.setOptions(new Options(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. return responseMessageContext;
  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. protected void handleResponse(MessageContext responseMessageContext) throws AxisFault {
  2. responseMessageContext.setSoapAction((String)null);
  3. SOAPEnvelope resenvelope;
  4. if(responseMessageContext.getEnvelope() == null) {
  5. resenvelope = TransportUtils.createSOAPMessage(responseMessageContext);
  6. if(resenvelope == null) {
  7. throw new AxisFault(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. throw Utils.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. public boolean hasFault() {
  2. QName payloadQName = this.getPayloadQName_Optimized();
  3. if(payloadQName != null && "Fault".equals(payloadQName.getLocalPart())) {
  4. String body1 = 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. SOAPBody body = this.getBody();
  8. return body == 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);

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

时间: 2024-10-11 01:54:46

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

Apache axis2 + Eclipse 开发 WebService

一.简介 Apache Axis2是下一代 Apache Axis.Axis2 虽然由 Axis 1.x 处理程序模型提供支持,但它具有更强的灵活性并可扩展到新的体系结构.Axis2 基于新的体系结构进行了全新编写,而且没有采用 Axis 1.x 的常用代码.支持开发 Axis2 的动力是探寻模块化更强.灵活性更高和更有效的体系结构,这种体系结构可以很容易地插入到其他相关 Web 服务标准和协议(如 WS-Security.WS-ReliableMessaging 等)的实现中.Apache A

译: 2. Apache Axis2安装指南

Apache Axis2安装指南 本文档提供有关Axis2分发包,系统先决条件以及设置环境变量和工具的信息,然后提供有关安装方法的详细说明. 请将您的反馈发送至:[email protected] 邮件列表.(订阅详情可在Axis2网站上获得.)请为每个电子邮件主题添加前缀[Axis2]. 内容 Axis2分布 系统要求 使用标准二进制分发将Axis2安装为独立服务器 安装Apache Axis2二进制分发版 启动Axis2 Standalone Server 使用标准二进制分发构建Axis2

axis2 webservice在websphere上需要设置was共享库

由于websphere自带的JAR包与axis2包冲突,要解决这个冲突,必须设置共享库. 在websphere控制台,找到环境>>>共享库,设置一个Cell类型的共享库,共享库名称为axis2,库包为: axis2-adb-1.5.6.jar axis2-kernel-1.5.6.jar axis2-transport-http-1.5.6.jar axis2-transport-local-1.5.6.jar axis2-jaxws-1.5.6.jar commons-fileuplo

axis2 webservice 调用的三种方式

[java] view plaincopy package testClick.src.test; import javax.xml.namespace.QName; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; impo

WebService学习之旅(六)使用Apache Axis2实现WebService客户端调用

上节介绍了如何使用Axis2 发布一个WebService,Axis2除了为我们编写WebService应用带来了便利,也同样简化的客户端调用的过程,本节在上节的基础上使用Axis2自带的工具生成客户端调用辅助类,并实现客户端调用代码的编写. 1.將前面下载的axis2-1.7.1-bin.zip解压,新建一个环境变量AXIS2_HOME,值为解压后目录路径.接着在path变量中添加%AXIS2_HOME%/bin;. 2.Eclipse中新建一个Java Project,打开Windows控制

axis2 WebService的发布与调用

1:准备:    JDK:http://www.oracle.com/technetwork/java/javase/downloads/jdk6downloads-1902814.html eclipse:http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/juno/SR2/eclipse-jee-juno-SR2-win32.zip tomcat:http://tomcat.

axis2 webService开发指南(3)

复杂对象类型的WebService 这次我们编写复杂点的WebService方法,返回的数据是我们定义属性带getter.setter方法JavaBean,一维数组.二维数组等 1.服务源代码 新建一个web project项目 代码如下: package com.amy.service.imple; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util

java axis2 webservice 接口的开发搭建和demo

1.先创建一个web项目,名字叫testAxis2Demo 2.下载axit2 的war包,地址是:http://apache.fayea.com//axis/axis2/java/core/1.6.2/axis2-1.6.2-war.zip 3.将下载axit2中war包下的WEB-INF/lib/ 下所有的jar包,copy下来,放在web项目下的lib目录中 4.在web.xml 中添加如下配置: <servlet> <servlet-name>AxisServlet<

eclipse+axis2+webservice开发实例

1.参考文献: 1.利用Java编写简单的WebService实例  http://nopainnogain.iteye.com/blog/791525 2.Axis2与Eclipse整合开发Web Service  http://tech.ddvip.com/2009-05/1242968642120461.html 3.http://blog.csdn.net/lightao220/article/details/3489015 4.http://clq9761.iteye.com/blog