问题的起因是修改了Axis2自动生成的代码,以便在后台打印出请求和响应的格式
public com.sean.AddResponse add(com.sean.Add add0) throws java.rmi.RemoteException { org.apache.axis2.context.MessageContext _messageContext = null; org.apache.axiom.soap.SOAPEnvelope env = null; org.apache.axiom.soap.SOAPEnvelope _returnEnv = null; try { ...... env = toEnvelope(getFactory(_operationClient.getOptions() .getSoapVersionURI()), add0, optimizeContent(new javax.xml.namespace.QName( "http://sean.com", "add")), new javax.xml.namespace.QName("http://sean.com", "add")); ...... _returnEnv = _returnMessageContext.getEnvelope(); java.lang.Object object = fromOM(_returnEnv.getBody() .getFirstElement(), com.sean.AddResponse.class, getEnvelopeNamespaces(_returnEnv)); return (com.sean.AddResponse) object; } catch (org.apache.axis2.AxisFault f) { ...... } finally { System.out.println("request:+\n" + env.toString()); System.out.println("response:\n" + _returnEnv.toString()); if (_messageContext.getTransportOut() != null) { _messageContext.getTransportOut().getSender().cleanup(_messageContext); } } }
虽然后台能够打印出请求,但是在打印响应时却会抛出异常:org.apache.axiom.om.NodeUnavailableException
主要还是代码修改的有问题,AXIS2的版本为1.6.2,在其lib包中的AXIOM版本为1.2.13,在我的工程中将其换为1.2.14
在AXIOM1.2.14的API中(参见:https://ws.apache.org/axiom/apidocs/org/apache/axiom/om/NodeUnavailableException.html)提到:
Exception indicating that a requested node cannot be returned because it is no longer available. A node may become unavailable because it has been consumed by a method such asOMSerializable.serializeAndConsume(XMLStreamWriter) orOMContainer.getXMLStreamReaderWithoutCaching(), or because one of its ancestors has been discarded usingOMNode.discard().
在获得_returnEnv对象后,调用了fromOM方法获得结果对象,fromOM方法如下:
private java.lang.Object fromOM(org.apache.axiom.om.OMElement param, java.lang.Class type, java.util.Map extraNamespaces) throws org.apache.axis2.AxisFault { try { if (com.sean.Add.class.equals(type)) { return com.sean.Add.Factory.parse(param .getXMLStreamReaderWithoutCaching()); } if (com.sean.AddResponse.class.equals(type)) { return com.sean.AddResponse.Factory.parse(param .getXMLStreamReaderWithoutCaching()); } } catch (java.lang.Exception e) { throw org.apache.axis2.AxisFault.makeFault(e); } return null; }
_returnEnv的类型是org.apache.axiom.soap.SOAPEnvelope,而org.apache.axiom.soap.SOAPEnvelope是org.apache.axiom.om.OMContainer的子类
所以在finally块中调用_returnEnv.toString()时,由于_returnEnv中保存的节点因为被OMContainer.getXMLStreamReaderWithoutCaching()方法消费而变得不可用,所以将抛出NodeUnavailableException异常
解决方式如下:
public com.sean.AddResponse add(com.sean.Add add0) throws java.rmi.RemoteException { org.apache.axis2.context.MessageContext _messageContext = null; org.apache.axiom.soap.SOAPEnvelope env = null; org.apache.axiom.soap.SOAPEnvelope _returnEnv = null; String request = ""; String response = ""; try { ...... env = toEnvelope(getFactory(_operationClient.getOptions() .getSoapVersionURI()), add0, optimizeContent(new javax.xml.namespace.QName( "http://sean.com", "add")), new javax.xml.namespace.QName("http://sean.com", "add")); request = env.toString(); ...... _returnEnv = _returnMessageContext.getEnvelope(); response = _returnEnv.toString(); java.lang.Object object = fromOM(_returnEnv.getBody() .getFirstElement(), com.sean.AddResponse.class, getEnvelopeNamespaces(_returnEnv)); return (com.sean.AddResponse) object; } catch (org.apache.axis2.AxisFault f) { ...... } finally { System.out.println("request:+\n" + request); System.out.println("response:\n" + response); if (_messageContext.getTransportOut() != null) { _messageContext.getTransportOut().getSender().cleanup(_messageContext); } } }