使用AXIS2创建的ADB-stub在客户端获取原始XML SOAP响应 [英] Getting raw XML SOAP-response on client side using ADB-stubs created by AXIS2
问题描述
我使用AXIS2创建的ADB-stub访问SOAP服务。我想记录服务返回的任何Axis Fault的原始XML响应。我可以将这些错误捕获为ServiceError。但是,我找不到一种方法来检索原始XML(参见下面的示例)。
I access a SOAP service using ADB-stubs created by AXIS2. I would like to log the raw XML response of any Axis Fault, that is returned by the service. I can catch those errors as "ServiceError". However, I do not find a way to retreive the raw XML (see example below).
我找到了一种方法来访问原始XML请求/响应以进行常规处理,使用getOMElement(参见下面的示例)。但是,这不适用于错误。
I found a way to access the raw XML request / response for regular processing, using getOMElement (see example below). However, this does not work for faults.
如何使用ADB存根获取原始XML错误?
How do I get the raw XML fault using ADB stubs?
示例Java代码:
public void testRequest(String URL) throws AxisFault {
MyServiceStub myservice = new MyServiceStub(URL);
MyRequest req = new MyRequest();
try {
TypeMyFunctionResponse response = myservice.myFunction(req);
// logging full soap response
System.out.println("SOAP Response: "
+ response.getOMElement(null,
OMAbstractFactory.getOMFactory())
.toStringWithConsume());
} catch (RemoteException e) {
//...
} catch (ServiceError e) {
// how to get the raw xml?
}
}
示例故障响应,我想要获取和log:
Example fault response, that I would like to fetch and log:
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body>
<soapenv:Fault>
<soapenv:Code>
<soapenv:Value>soapenv:Receiver</soapenv:Value>
</soapenv:Code>
<soapenv:Reason>
<soapenv:Text xml:lang="en-US">service error</soapenv:Text>
</soapenv:Reason>
<soapenv:Detail>
<ns1:error xmlns:ns1="http://www.somehost.com/webservices/someservice">
<ns1:code>500</ns1:code>
<ns1:messageText>some fault message</ns1:messageText>
</ns1:error>
</soapenv:Detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
推荐答案
根据joergl的建议,我将ADB-stubs更改为JAX-WS-one使用SOAPHandler来记录请求,响应和故障,如下所示: http://www.mkyong.com/webservices/jax-ws/jax-ws-soap-handler-in-client-side/
As suggested by joergl I changed my ADB-stubs to JAX-WS-ones using a "SOAPHandler" to log requests, responses and faults following the description here: http://www.mkyong.com/webservices/jax-ws/jax-ws-soap-handler-in-client-side/
我的处理程序看起来像是使用log4j记录格式良好的XML:
My handler looks like this for logging the nicely formated XML using log4j:
public class RequestResponseHandler implements SOAPHandler<SOAPMessageContext> {
private static Logger log = Logger.getLogger(RequestResponseHandler.class);
private Transformer transformer = null;
private DocumentBuilderFactory docBuilderFactory = null;
private DocumentBuilder docBuilder = null;
public RequestResponseHandler() {
try {
transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "5");
docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilder = docBuilderFactory.newDocumentBuilder();
} catch (TransformerConfigurationException
| TransformerFactoryConfigurationError
| ParserConfigurationException e) {
log.error(e.getMessage(), e);
}
}
@Override
public void close(MessageContext arg0) {
}
@Override
public boolean handleFault(SOAPMessageContext messageContext) {
log(messageContext);
return true;
}
@Override
public boolean handleMessage(SOAPMessageContext messageContext) {
log(messageContext);
return true;
}
private void log(SOAPMessageContext messageContext) {
String xml = "";
SOAPMessage msg = messageContext.getMessage();
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
msg.writeTo(out);
xml = out.toString("UTF-8");
} catch (Exception e) {
log.error(e.getMessage(),e);
}
String direction = "";
Boolean outbound = (Boolean) messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outbound) {
direction += "Request: \n";
} else {
direction += "Response: \n";
}
log.info(direction + getXMLprettyPrinted(xml));
}
@Override
public Set<QName> getHeaders() {
return Collections.emptySet();
}
public String getXMLprettyPrinted(String xml) {
if (transformer == null || docBuilder == null)
return xml;
InputSource ipXML = new InputSource(new StringReader(xml));
Document doc;
try {
doc = docBuilder.parse(ipXML);
StringWriter stringWriter = new StringWriter();
StreamResult streamResult = new StreamResult(stringWriter);
DOMSource domSource = new DOMSource(doc);
transformer.transform(domSource, streamResult);
return stringWriter.toString();
} catch (SAXException | IOException | TransformerException e) {
log.error(e.getMessage(), e);
return xml;
}
}
}
此外我想重复使用我的应用程序代码中的原始XML。所以我不得不将这些数据从SOAPHandler传回我的客户端代码。怎么做不太明显。有关此问题的更多信息,请参阅以下文章:
如何将其他字段与soapMessage一起发送到soap处理程序?
In addition I wanted to reuse the raw XML in my application code. So I had to transfer this data from the SOAPHandler back to my client code. How to this was not too obvious. More about this problem can be found in this article: How to send additional fields to soap handler along with soapMessage?
这篇关于使用AXIS2创建的ADB-stub在客户端获取原始XML SOAP响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!