Java 动态 WSDL 的 WS 客户端实现
Java WS Client implementation for dynamic WSDL
我正在寻找一种从每 3 个月更改一次的 WSDL 实现 Java Web 服务客户端的方法,而无需重新生成客户端 jar。
如有任何帮助,我们将不胜感激。
如果 Web 服务很简单,您可以使用面向 "DOM" 的方法,在这种方法中,您以编程方式 create/modify 您在请求中发送的 XML 文档,并类似地提取值来自响应中返回的 XML。
它并不像听起来那么糟糕。 API 是相当高级的。例如调用时:
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
this.soapConnection = soapConnectionFactory.createConnection();
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("ser", "http://server.splat/");
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement(operation, "ser");
int n = 0;
for (Object argN : args) {
SOAPElement soapBodyElemN = soapBodyElem.addChildElement("arg" + n++);
soapBodyElemN.addTextNode(argN.toString());
}
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", "\"\"");
soapMessage.saveChanges();
/* Print the request message */
debug(operation + " Request SOAP Message:\n" + traceSOAPMessage(soapMessage));
SOAPMessage soapResponse = this.soapConnection.call(
soapMessage, this.url
);
然后您只需从 soapResponse
:
中提取值
Iterator it = soapResponse.getSOAPBody().getChildElements(
envelope.createName(operation + "Response", null, "http://server.splat/")
);
soapBodyElem = (SOAPElement) it.next();
it = soapBodyElem.getChildElements(
envelope.createName("return")
);
while (it.hasNext()) {
String value = ((SOAPElement) it.next()).getTextContent();
System.out.println(value);
}
这种 Web 服务调用方式可以承受对 WSDL 的任何微小更改。此外,它更紧凑,因为您不需要管理大量自动生成的 class 文件。
在我看来,这是一种更 "honest" 的方法,因为您不会 "pretending" 调用本地方法 RPC 样式。
当然,如果你的 XML 对象的结构以任何显着的方式来回变化,这将不起作用,但如果你了解你期望它改变的方式,你可以以预期这种方式开发您的应用程序逻辑,甚至使其可配置,以便无需重新部署即可发生更改。
我正在寻找一种从每 3 个月更改一次的 WSDL 实现 Java Web 服务客户端的方法,而无需重新生成客户端 jar。
如有任何帮助,我们将不胜感激。
如果 Web 服务很简单,您可以使用面向 "DOM" 的方法,在这种方法中,您以编程方式 create/modify 您在请求中发送的 XML 文档,并类似地提取值来自响应中返回的 XML。
它并不像听起来那么糟糕。 API 是相当高级的。例如调用时:
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
this.soapConnection = soapConnectionFactory.createConnection();
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("ser", "http://server.splat/");
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement(operation, "ser");
int n = 0;
for (Object argN : args) {
SOAPElement soapBodyElemN = soapBodyElem.addChildElement("arg" + n++);
soapBodyElemN.addTextNode(argN.toString());
}
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", "\"\"");
soapMessage.saveChanges();
/* Print the request message */
debug(operation + " Request SOAP Message:\n" + traceSOAPMessage(soapMessage));
SOAPMessage soapResponse = this.soapConnection.call(
soapMessage, this.url
);
然后您只需从 soapResponse
:
Iterator it = soapResponse.getSOAPBody().getChildElements(
envelope.createName(operation + "Response", null, "http://server.splat/")
);
soapBodyElem = (SOAPElement) it.next();
it = soapBodyElem.getChildElements(
envelope.createName("return")
);
while (it.hasNext()) {
String value = ((SOAPElement) it.next()).getTextContent();
System.out.println(value);
}
这种 Web 服务调用方式可以承受对 WSDL 的任何微小更改。此外,它更紧凑,因为您不需要管理大量自动生成的 class 文件。
在我看来,这是一种更 "honest" 的方法,因为您不会 "pretending" 调用本地方法 RPC 样式。
当然,如果你的 XML 对象的结构以任何显着的方式来回变化,这将不起作用,但如果你了解你期望它改变的方式,你可以以预期这种方式开发您的应用程序逻辑,甚至使其可配置,以便无需重新部署即可发生更改。