[Axis2]org.apache.axiom.om.NodeUnavailableException

问题的起因是修改了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);
		}
	}
}

 

你可能感兴趣的:(webservice,axis2,axiom)