我使用AXIS2创建的ADB-stub访问SOAP服务.我想记录服务返回的任何Axis Fault的原始XML响应.我可以将这些错误视为"ServiceError".但是,我找不到一种方法来检索原始XML(参见下面的示例).
我找到了一种使用getOMElement访问原始XML请求/响应以进行常规处理的方法(参见下面的示例).但是,这不适用于故障.
如何使用ADB存根获取原始XML错误?
示例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?
}
}
Run Code Online (Sandbox Code Playgroud)
示例故障响应,我想获取并记录:
<?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>
Run Code Online (Sandbox Code Playgroud)
小智 7
以下是您可能正在寻找的内容,yourStub
是您通过wsdl2java生成的内容,并在您提出请求后使用下面的行.lastOperation
当您拨打实际电话时,该消息设置为并发送:
request = yourStub._getServiceClient().getLastOperationContext().getMessageContext("Out")
.getEnvelope().toString());
response = yourStub._getServiceClient().getLastOperationContext().getMessageContext("In")
.getEnvelope().toString());
Run Code Online (Sandbox Code Playgroud)
希望这很有帮助.
虽然这个问题已经得到了很好的回答,但我需要提前做到这一点,并且无法找到适合我的约束的合适答案,因此我为后代添加了自己的答案.
对于最近运行JDK 1.4的项目,我需要使用Axis 2版本1.4.1执行此操作,而JAX-WS存根不支持我所阅读的内容.我最后通过使用我自己的构建器类包装SoapBuilder来捕获输入时保留ADB存根,复制输入流并将副本传递给SoapBuilder:
public class SOAPBuilderWrapper implements Builder {
private String lastResponse;
private SOAPBuilder builder = new SOAPBuilder();
private static final int BUFFER_SIZE = 8192;
public OMElement processDocument(InputStream inputStream,
String contentType, MessageContext messageContext) throws AxisFault {
ByteArrayOutputStream copiedStream = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = inputStream.read(buffer);
while (bytesRead > -1) {
copiedStream.write(buffer, 0, bytesRead);
bytesRead = inputStream.read(buffer);
}
lastResponse = copiedStream.toString();
} catch (IOException e) {
throw new AxisFault("Can't read from input stream", e);
}
return builder.processDocument(
new ByteArrayInputStream(copiedStream.toByteArray()),
contentType, messageContext);
}
public String getLastResponse() {
return lastResponse;
}
}
Run Code Online (Sandbox Code Playgroud)
由于各种原因,使用axis2.xml进行配置存在问题,因此以编程方式添加了包装器,其中包含以下内容:
SoapBuilderWrapper responseCaptor = new SoapBuilderWrapper();
AxisConfiguration axisConfig = stub._getServiceClient().getAxisConfiguration();
axisConfig.addMessageBuilder("application/soap+xml", responseCaptor);
axisConfig.addMessageBuilder("text/xml", responseCaptor);
Run Code Online (Sandbox Code Playgroud)
这允许在调用服务后使用responseCaptor.getLastResponse()检索响应.
按照 joergl 的建议,我使用“SOAPHandler”将我的 ADB-stubs 更改为 JAX-WS-ones,以按照此处的描述记录请求、响应和故障:http://www.mkyong.com/webservices/jax-ws/jax -ws-soap-handler-in-client-side/
我的处理程序如下所示,用于使用 log4j 记录格式良好的 XML:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
此外,我想在我的应用程序代码中重用原始 XML。因此,我必须将这些数据从 SOAPHandler 传输回我的客户端代码。如何做到这一点还不太明显。有关此问题的更多信息可以在本文中找到: 如何将附加字段与soapMessage一起发送到soap处理程序?
归档时间: |
|
查看次数: |
35169 次 |
最近记录: |