由于项目的需要,需要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);
| |