浙林龙哥

   :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
关于axis2中对soapfault的处理的一个小bug
gjs0064114    更新:2006-04-27 21:56:07  $version   

由于项目的需要,需要axis2的客户端能够对服务端返回的soap fault 进行处理。但在实际中发现axis2对soapfault处理中有问题
首先,(1)明确一下axis2 engine  接收到的soapfault 消息的格式:

HTTP/1.1 500 Internal Server Error

Server: gSOAP/2.7

Content-Type: text/xml; charset=utf-8

Content-Length: 1916

Connection: close



<?xml version="1.0" encoding="UTF-8"?>
   <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss- 
      <SOAP-ENV:Body>
         <SOAP-ENV:Fault>
            <faultcode>SOAP-ENV:Server</faultcode>
            <faultstring>The value of structure ns2__Register is NULL</faultstring>
            <detail>
               <a:egoerror xmlns:a="http://www.ego.com/" >
                  <a:a>error String</a:a>
                  <a:b>error code </a:b>
               </a:egoerror>
            </detail>
         </SOAP-ENV:Fault>
      </SOAP-ENV:Body>
   </SOAP-ENV:Envelope>
(2)在axis2将soapfault消息封装到axisfault的代码如下:
 org.apache.axis2.clientapi.OutMEPClient.java
.....

    public MessageContext invokeBlocking(OperationDescription axisop,
                                         final MessageContext msgctx)
            throws AxisFault {
        prepareInvocation(axisop, msgctx);

        // The message ID is sent all the time
        String messageID = String.valueOf(System.currentTimeMillis());
        msgctx.setMessageID(messageID);
        //
        if (useSeparateListener) {
            //This mean doing a Request-Response invocation using two channel. If the
            //transport is two way transport (e.g. http) Only one channel is used (e.g. in http cases
            //202 OK is sent to say no repsone avalible). Axis2 get blocked return when the response is avalible.

            SyncCallBack callback = new SyncCallBack();
            //this method call two channel non blocking method to do the work and wait on the callbck
            invokeNonBlocking(axisop, msgctx, callback);
            long index = timeOutInMilliSeconds / 100;
            while (!callback.isComplete()) {
                //wait till the reponse arrives
                if (index-- >= 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new AxisFault(e);
                    }
                } else {
                    throw new AxisFault(Messages.getMessage("responseTimeOut"));
                }
            }
            //process the resule of the invocation
            if (callback.envelope != null) {
                MessageContext resMsgctx =
                        new MessageContext(serviceContext.getEngineContext());
                resMsgctx.setEnvelope(callback.envelope);
                return resMsgctx;
            } else {
                if (callback.error instanceof AxisFault) {
                    throw (AxisFault) callback.error;
                } else {
                    throw new AxisFault(callback.error);
                }
            }
        } else {
            //This is the Usual Request-Response Sync implemetation
            msgctx.setTo(to);
            msgctx.setServiceContext(serviceContext);
            ConfigurationContext syscontext = serviceContext.getEngineContext();
            msgctx.setConfigurationContext(syscontext);

            checkTransport(msgctx);

            //find and set the Operation Context
            ConfigurationContext sysContext = serviceContext.getEngineContext();
            AxisConfiguration registry = sysContext.getAxisConfiguration();
            msgctx.setOperationContext(OperationContextFactory.createOperationContext(WSDLConstants.MEP_CONSTANT_IN_OUT,
                    axisop,
                    serviceContext));
            //Send the SOAP Message and receive a response
            MessageContext response =
                    TwoWayTransportBasedSender.send(msgctx, listenerTransport);

            //check for a fault and return the result
            SOAPEnvelope resenvelope = response.getEnvelope();
            if (resenvelope.getBody().hasFault()) {
                SOAPFault soapFault = resenvelope.getBody().getFault();
                Exception ex = soapFault.getException();

                if (isExceptionToBeThrownOnSOAPFault) {
                    //does the SOAPFault has a detail element for Excpetion
                    if (ex != null) {
                        throw new AxisFault(ex);
                    } else {
                        //if detail element not present create a new Exception from the detail
                        String message = "";


                        message = message + "Code =" + soapFault.getCode()==null?"":
                                soapFault.getCode().getValue()==null?"":soapFault.getCode().getValue().getText();
           

                        message = message + "Reason =" + soapFault.getReason()==null?"":
                                soapFault.getReason().getSOAPText()==null?"":soapFault.getReason().getSOAPText().getText();
                        System.out.println("message "+message);
                        throw new AxisFault(message);
                    }
                }
            }
            return response;
        }
    }

.....
应改为
                  message = message + "Code =" + (soapFault.getCode()==null?"":
                                soapFault.getCode().getValue()==null?"":soapFault.getCode().getValue().getText());
                        System.out.println(""+message);
                       Iterator t=   soapFault.getDetail().getAllDetailEntries();
                        loop(t,1);
                        org.apache.axis2.soap.impl.llom.SOAPFaultDetailImpl a;

                        message = message + "Reason =" + (soapFault.getReason()==null?"":
                                soapFault.getReason().getSOAPText()==null?"":soapFault.getReason().getSOAPText().getText());
这段代码只是对<faultcode><faultstring>进行了处理
而对于<detail>并未处理

3)可以自行对代码修改处理<detail>部分。



    public void loop(Iterator t,int i ){
      OMElementImpl omE;
      OMTextImpl omT;
      Object tx;
      char [] sapace1=new char[i];
      String sapace=new String(sapace1);
      OMChildrenIterator tor=(OMChildrenIterator)t;
      while ( t.hasNext()){
    tx= t.next();
    System.out.println(sapace+tx.getClass().getName());
    if(tx instanceof OMElementImpl){
    omE=(OMElementImpl)tx;
    System.out.println(sapace+omE.getText());
      loop(omE.getChildren()  ,i+1);
    }else if(tx instanceof OMTextImpl)
    { omT=(OMTextImpl)tx;
      System.out.println(sapace+omT.getText());
    }else{
    System.out.println(sapace+"other type");
    }
      }
}

并在一下处调用该函数
                    if (ex != null) {
                        throw new AxisFault(ex);
                    } else {
                        //if detail element not present create a new Exception from the detail
                        String message = "";


                        message = message + "Code =" + (soapFault.getCode()==null?"":
                                soapFault.getCode().getValue()==null?"":soapFault.getCode().getValue().getText());
                        System.out.println(""+message);
                       Iterator t=   soapFault.getDetail().getAllDetailEntries();
                        loop(t,1);
posted on 2008-04-09 23:05  浙林龙哥  阅读(2373)  评论(0编辑  收藏  举报