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

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

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

  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. }
  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.  
  15. OperationClient opClient = serviceClient.createClient(ServiceClient.ANON_OUT_IN_OP);
  16. opClient.addMessageContext(requetMessageContext);
  17. opClient.setOptions(options);
  18. opClient.execute(true);
  19. MessageContext rspMC = opClient.getMessageContext("In");
  20. response = rspMC.getEnvelope().getBody().getFirstElement();
  21. log.info("应答报文: "+ rspMC.getEnvelope());
  22. } catch (AxisFault e) {
  23. this.errRspDesc = "xxxxx";
  24. log.error("soapDispatch AxisFault!");
  25. throw e;
  26. } catch (Exception e) {
  27. this.errRspDesc = "xxxxxxxxxxxxx!";
  28. log.error("soapDispatch Exception!");
  29. throw e;
  30. }

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

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

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

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

  1. public final void execute(boolean block) throws AxisFault {
  2. this.sc.setLastOperationContext(this.oc);
  3. this.executeImpl(block);
  4. }
  1. public final void execute(boolean block) throws AxisFault {
  2. this.sc.setLastOperationContext(this.oc);
  3. this.executeImpl(block);
  4. }

再看this.executeImpl(block);

  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. }
  1. public void executeImpl(boolean block) throws AxisFault {
  2. if(log.isDebugEnabled()) {
  3. log.debug("Entry: OutInAxisOperationClient::execute, " + block);
  4. }
  5.  
  6. if(this.completed) {
  7. throw new AxisFault(Messages.getMessage("mepiscomplted"));
  8. } else {
  9. ConfigurationContext cc = this.sc.getConfigurationContext();
  10. MessageContext mc = this.oc.getMessageContext("Out");
  11. if(mc == null) {
  12. throw new AxisFault(Messages.getMessage("outmsgctxnull"));
  13. } else {
  14. this.prepareMessageContext(cc, mc);
  15. if(this.options.getTransportIn() == null && mc.getTransportIn() == null) {
  16. mc.setTransportIn(ClientUtils.inferInTransport(cc.getAxisConfiguration(), this.options, mc));
  17. } else if(mc.getTransportIn() == null) {
  18. mc.setTransportIn(this.options.getTransportIn());
  19. }
  20.  
  21. boolean useAsync = false;
  22. if(!mc.getOptions().isUseSeparateListener()) {
  23. Boolean replyTo = (Boolean)mc.getProperty("UseAsyncOperations");
  24. if(log.isDebugEnabled()) {
  25. log.debug("OutInAxisOperationClient: useAsyncOption " + replyTo);
  26. }
  27.  
  28. if(replyTo != null) {
  29. useAsync = replyTo.booleanValue();
  30. }
  31. }
  32.  
  33. EndpointReference replyTo1 = mc.getReplyTo();
  34. if(replyTo1 != null) {
  35. if(replyTo1.hasNoneAddress()) {
  36. throw new AxisFault(replyTo1.getAddress() + "" + " can not be used with OutInAxisOperationClient , user either " + "fireAndForget or sendRobust)");
  37. }
  38.  
  39. if(replyTo1.isWSAddressingAnonymous() && replyTo1.getAllReferenceParameters() != null) {
  40. mc.setProperty("includeOptionalHeaders", Boolean.TRUE);
  41. }
  42.  
  43. String customReplyTo = (String)this.options.getProperty(Options.CUSTOM_REPLYTO_ADDRESS);
  44. if(!Options.CUSTOM_REPLYTO_ADDRESS_TRUE.equals(customReplyTo) && !replyTo1.hasAnonymousAddress()) {
  45. useAsync = true;
  46. }
  47. }
  48.  
  49. if(!useAsync && !mc.getOptions().isUseSeparateListener()) {
  50. if(block) {
  51. this.send(mc);
  52. this.completed = true;
  53. } else {
  54. this.sc.getConfigurationContext().getThreadPool().execute(new OutInAxisOperationClient.NonBlockingInvocationWorker(this.callback, mc, this.axisCallback));
  55. }
  56. } else {
  57. this.sendAsync(useAsync, mc);
  58. }
  59.  
  60. }
  61. }
  62. }

进send(mc)方法

  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. }
  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. }

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

  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. }
  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.  
  10. responseMessageContext.setEnvelope(resenvelope);
  11. }
  12.  
  13. resenvelope = responseMessageContext.getEnvelope();
  14. if(resenvelope != null) {
  15. AxisEngine.receive(responseMessageContext);
  16. if(responseMessageContext.getReplyTo() != null) {
  17. this.sc.setTargetEPR(responseMessageContext.getReplyTo());
  18. }
  19.  
  20. resenvelope = responseMessageContext.getEnvelope();
  21. if((resenvelope.hasFault() || responseMessageContext.isProcessingFault()) && this.options.isExceptionToBeThrownOnSOAPFault()) {
  22. throw Utils.getInboundFaultFromMessageContext(responseMessageContext);
  23. }
  24. }
  25.  
  26. }

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

  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. }
  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. }

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

  1. options.setExceptionToBeThrownOnSOAPFault(false);
  1. options.setExceptionToBeThrownOnSOAPFault(false);

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

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

  1. WebService学习之旅(四)Apache Axis2的安装

    一.Axis2简介 Axis2是目前使用较多的WebService引擎,它是Axis1.x的升级版本,不仅支持SOAP1.1和SOAP1.2,而且也提供了对REST风格WebService的支持. A ...

  2. Apache axis2 + Eclipse 开发 WebService

    yd小结注意:1.axis2的2个插件的版本必须与引入的jar包匹配,如果不同则可能报以下错误 “没有实现序列化方法”或 “org.apache.axis2.databinding.utils.wri ...

  3. Axis2 WebService客户端Axis2调用

    第一RPC方式,不生成客户端代码 第二,document方式,不生成客户端代码 第三,用wsdl2java工具,生成客户端方式调用 package samples.quickstart.client; ...

  4. axis2 webservice jar包使用情况(转)

    原文地址:axis2 webservice jar包使用情况 今天使用axis2webservice,整理了下jar包,方便以后时候. axis2 webservice 服务端jar包: --> ...

  5. org.apache.axis2.AxisFault: java.lang.Error: Unresolved compilation problem:

    原创:转载请注明出处 今天遇到以下一个异常,找了好长时间,就是不知道什么原因, 在网上搜了好多,也没搜到相关的解决方法. 1.异常展示, org.apache.axis2.AxisFault: jav ...

  6. 2.1 Apache Axis2 快速学习手册之 POJO 构建Web Service

    1. 准备:创建一个Maven Web App 项目 这里让我们使用Maven 模板创建一个Web App 项目 1. New------> Maven Project 2. 使用默认配置,点击 ...

  7. 译: 2. Apache Axis2安装指南

    Apache Axis2安装指南 本文档提供有关Axis2分发包,系统先决条件以及设置环境变量和工具的信息,然后提供有关安装方法的详细说明. 请将您的反馈发送至:java-dev@axis.apach ...

  8. org.apache.axis2.AxisFault: org.apache.axis2.databinding.ADBException: Unexpected subelement profile

    原创:转载请注明出处 1.异常情况 org.apache.axis2.AxisFault: org.apache.axis2.databinding.ADBException: Unexpected ...

  9. axis2 webservice 发布、调用与项目集成

    发布 1.在apache官网下载axis2包,下载Binary Distribution和War Distribution两个zip. 2.将war放入tomcat webapps下部署.并输入 ht ...

随机推荐

  1. Mysql中错误日志、binlog日志、查询日志、慢查询日志简单介绍

    前言 数据库的日志是帮助数据库管理员,追踪分析数据库以前发生的各种事件的有力根据.mysql中提供了错误日志.binlog日志(二进制日志).查处日志.慢查询日志.在此,我力求解决下面问题:各个日志的 ...

  2. Erlang 又生虫了

    好久不玩Erlang了.近期想鼓捣Eresye,下了个最新版OTP 17,结果.发现了问题. 安装这个最新版的Erlang (erl 6.0)后,用erlc编译了Eresye 1.2.5,并放入其li ...

  3. nyist oj 19 擅长排列的小明(dfs搜索+STL)

    擅长排列的小明 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描写叙述 小明十分聪明.并且十分擅长排列计算.比方给小明一个数字5,他能立马给出1-5按字典序的全排列,假设你想 ...

  4. Unity3D 玻璃 Shader

     Shader "Custom/Glass" { // Upgrade NOTE: replaced 'SeperateSpecular' with 'SeparateSpec ...

  5. C#之快速排序 C#之插入排序 C#之选择排序 C#之冒泡排序

    C#之快速排序   算法描述 1.假定数组首位元素为“枢轴”,设定数列首位(begin)与末位(end)索引: 2.由末位索引对应元素与“枢轴”进行比较,如果末位索引对应元素大于“枢轴”元素,对末位索 ...

  6. 玩转单元測试之DBUnit

    本文同一时候发表在:http://www.cnblogs.com/wade-xu/p/4547381.html DBunit 是一种扩展于JUnit的数据库驱动測试框架,它使数据库在測试过程之间处于一 ...

  7. win下IE设置

    当win7系统时需要升级IE为11版本,需要先安装sp1版本补丁,再装IE11,若还是装不了,可借助第三方平台(电脑管家等)升级安装.或 更新系统再安装IE11 https://jingyan.bai ...

  8. ios30---pthread, NSThread, GCD, NSOperation

    pthread(线程库,很早就有的技术,了解):一套通用的多线程API适用于Unix\Linux\Windows等系统(java开发也有pthread)跨平台\可移植使用难度大(全是C函数) C语言 ...

  9. fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt

    project->xx Properties->Manifest->Input and Output->Embed Manifest将yes修改为no

  10. 嵌入式Linux系统---ppp拨号,4G模块上网【转】

    本文转载自:http://blog.csdn.net/qq562029186/article/details/65438553 4G模块PPP拨号上网 方法1 所需文件: xxx-chat-conne ...