【发布时间】:2013-05-15 04:21:49
【问题描述】:
我在这里找到了许多关于如何从 JAX-WS 客户端检索 XML 响应的线程。在我的例子中,客户端是通过 Oracle 的 JDeveloper 产品从 WSDL 生成的,并将调用用 .NET 编写的 Document/Literal 服务端点。我想要做的是从调用客户端的调用中获取 XML 响应,而不是从处理程序内部。
我看到的最接近这个问题的线程是: http://www.coderanch.com/t/453537/Web-Services/java/capture-SoapRequest-xml-SoapResponse-xml
我认为我不想生成 Dispatch 调用,因为 SOAP 数据包的端点 XML 模式相当复杂,而且自动代理使调用变得微不足道。除非有其他方法来填充生成的 bean,然后调用一些简单地生成 XML 的方法,然后我进行调用?
private void storeSOAPMessageXml(SOAPMessageContext messageContext) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SOAPMessage soapMessage = messageContext.getMessage();
try {
soapMessage.writeTo(baos);
String responseXml = baos.toString();
log.debug("Response: " + responseXml );
PaymentGatewayXMLThreadLocal.set(responseXml);
} catch (SOAPException e) {
log.error("Unable to retrieve SOAP Response message.", e);
} catch (IOException e) {
log.error("Unable to retrieve SOAP Response message.", e);
}
}
我的想法是将调用的响应存储在处理程序内的 ThreadLocal 中,然后在调用后读取它。这合理吗?所以handler在handleMessage和handleFault中做了上述代码后,客户端调用代码调用这个方法:
@Override
public String getSOAPResponseXML(Object clientstub) {
String returnValue = PaymentGatewayXMLThreadLocal.get();
return returnValue;
} // getSOAPResponseXML
看来毕竟还有其他方法。在阅读jax-ws-handlers 之后,我看到处理程序可以引入一个应用程序范围的变量。我更改了处理程序来执行此操作:
private void storeSOAPMessageXml(SOAPMessageContext messageContext) {
String xml = getSOAPMessageXml(messageContext);
// YourPayXMLThreadLocal.set(xml);
// put it into the messageContext as well, but change scope
// default of handler Scope, and client can't read it from responsecontext!
messageContext.put(SOAP_RESPONSE_XML, xml);
messageContext.setScope(SOAP_RESPONSE_XML, MessageContext.Scope.APPLICATION );
} // storeSOAPMessageXml
客户端只是这样读取它:
@Override
public String getSOAPResponseXML(Object clientstub) {
String returnValue = null;
// works (assuming a threadlocal is ok)
// returnValue = YourPayXMLThreadLocal.get();
BindingProvider bindingProvider = (BindingProvider) clientstub;
// Thought this would work, but it doesn't - it returns null.
// Map<String, Object> requestContext = bindingProvider.getRequestContext();
// String returnValue = (String) requestContext.get(JaxWsClientResponseXmlHandler.SOAP_RESPONSE_XML);
// this works!!
Map<String, Object> responseContext = bindingProvider.getResponseContext();
System.out.println("has key? " + responseContext.containsKey(JaxWsClientResponseXmlHandler.SOAP_RESPONSE_XML));
returnValue = (String) responseContext.get(JaxWsClientResponseXmlHandler.SOAP_RESPONSE_XML);
return returnValue;
} // getSOAPResponseXML
【问题讨论】:
标签: java xml jax-ws soaphandler