如何从Java类做一个SOAP Web服务调用?

我对web服务世界相对陌生,我的研究似乎让我困惑不止,我的问题是我得到了一个库(jar),我必须使用一些web服务function来扩展它。

这个库将被分享给其他开发者,并且在jar中的类之间将会有一个调用webservice的方法(实质上是设置类的属性,做一些业务逻辑,比如把对象存储在一个db中,等等,并用这些修改发回对象)。 我想尽可能简单地调用这个服务,希望尽可能简单,以便开发者使用这个类只需要做。

Car c = new Car("Blue"); c.webmethod(); 

我一直在研究JAX-WS在服务器上使用,但在我看来,我不需要在服务器上创buildwsimport ,也不需要在客户端上创buildwsimport ,因为我知道两者都有类,我只需要一些交互在服务器和客户端共享的类之间。 您认为在网上服务和课堂中的呼叫有意义吗?

我明白你的问题归结为如何从Java调用SOAP(JAX-WS)Web服务并获得它的返回对象 。 在这种情况下,你有两种可能的方法:

  1. 通过wsimport生成Java类并使用它们; 要么
  2. 创build一个SOAP客户端:
    1. 将服务的参数序列化为XML;
    2. 通过HTTP操作调用Web方法; 和
    3. 将返回的XML响应parsing回对象。

关于第一种方法(使用wsimport ):

我看到你已经有了服务(实体或其他)的业务类,而且这个事实是wsimport生成了一个全新的类(它与你已有的类重复)。

但是,我担心,在这种情况下,您只能:

  • 修改(编辑) wsimport生成的代码,使其使用您的业务类(这很困难,不值得这样做 – 每当WSDL发生变化时,都要记住,您必须重新生成并重新调整代码)。 要么
  • 放弃并使用wsimport生成的类。 (在这个解决scheme中,您的业务代码可以将生成的类作为另一个架构层的服务使用)。

关于第二种方法(创build您的自定义SOAP客户端):

为了实施第二种方法,您必须:

  1. 拨打电话:
    • 使用SAAJ(SOAP with Attachments API for Java)框架(参见下文,随附Java SE 1.6或更高版本)来进行调用; 要么
    • 你也可以通过java.net.HttpUrlconnection (和一些java.io处理)来完成。
  2. 将对象从XML转换回来:
    • 使用OXM(对象到XML映射)框架(如JAXB)将XML从/到对象中序列化/反序列化
    • 或者,如果您必须手动创build/parsingXML(如果接收到的对象与发送的对象只有一点点差异,这可能是最好的解决scheme)。

使用经典的java.net.HttpUrlConnection创buildSOAP客户端并不困难(但也不是那么简单),你可以在这个链接中find一个非常好的起始代码。

我build议你使用SAAJ框架:

附带API的Java(SAAJ) SOAP主要用于直接处理任何Web Service API中幕后发生的SOAP请求/响应消息。 它允许开发人员直接发送和接收SOAP消息,而不是使用JAX-WS。

使用SAAJ查看SOAP Web服务调用的一个工作示例(运行它!)。 它调用这个Web服务 。

 import javax.xml.soap.*; public class SOAPClientSAAJ { // SAAJ - SOAP Client Testing public static void main(String args[]) { /* The example below requests from the Web Service at: https://www.w3schools.com/xml/tempconvert.asmx?op=CelsiusToFahrenheit To call other WS, change the parameters below, which are: - the SOAP Endpoint URL (that is, where the service is responding from) - the SOAP Action Also change the contents of the method createSoapEnvelope() in this class. It constructs the inner part of the SOAP envelope that is actually sent. */ String soapEndpointUrl = "https://www.w3schools.com/xml/tempconvert.asmx"; String soapAction = "https://www.w3schools.com/xml/CelsiusToFahrenheit"; callSoapWebService(soapEndpointUrl, soapAction); } private static void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException { SOAPPart soapPart = soapMessage.getSOAPPart(); String myNamespace = "myNamespace"; String myNamespaceURI = "https://www.w3schools.com/xml/"; // SOAP Envelope SOAPEnvelope envelope = soapPart.getEnvelope(); envelope.addNamespaceDeclaration(myNamespace, myNamespaceURI); /* Constructed SOAP Request Message: <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myNamespace="https://www.w3schools.com/xml/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <myNamespace:CelsiusToFahrenheit> <myNamespace:Celsius>100</myNamespace:Celsius> </myNamespace:CelsiusToFahrenheit> </SOAP-ENV:Body> </SOAP-ENV:Envelope> */ // SOAP Body SOAPBody soapBody = envelope.getBody(); SOAPElement soapBodyElem = soapBody.addChildElement("CelsiusToFahrenheit", myNamespace); SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("Celsius", myNamespace); soapBodyElem1.addTextNode("100"); } private static void callSoapWebService(String soapEndpointUrl, String soapAction) { try { // Create SOAP Connection SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance(); SOAPConnection soapConnection = soapConnectionFactory.createConnection(); // Send SOAP Message to SOAP Server SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(soapAction), soapEndpointUrl); // Print the SOAP Response System.out.println("Response SOAP Message:"); soapResponse.writeTo(System.out); System.out.println(); soapConnection.close(); } catch (Exception e) { System.err.println("\nError occurred while sending SOAP Request to Server!\nMake sure you have the correct endpoint URL and SOAPAction!\n"); e.printStackTrace(); } } private static SOAPMessage createSOAPRequest(String soapAction) throws Exception { MessageFactory messageFactory = MessageFactory.newInstance(); SOAPMessage soapMessage = messageFactory.createMessage(); createSoapEnvelope(soapMessage); MimeHeaders headers = soapMessage.getMimeHeaders(); headers.addHeader("SOAPAction", soapAction); soapMessage.saveChanges(); /* Print the request message, just for debugging purposes */ System.out.println("Request SOAP Message:"); soapMessage.writeTo(System.out); System.out.println("\n"); return soapMessage; } } 

关于使用JAXB进行序列化/反序列化,很容易find关于它的信息。 你可以从这里开始: http : //www.mkyong.com/java/jaxb-hello-world-example/ 。

或者使用Apache CXF的wsdl2java生成可以使用的对象。

它包含在你可以从他们的网站下载的二进制包。 你可以简单地运行一个像这样的命令:

 $ ./wsdl2java -p com.mynamespace.for.the.api.objects -autoNameResolution http://www.someurl.com/DefaultWebService?wsdl 

它使用wsdl来生成对象,你可以像这样使用(对象名也是从wsdl中抓取的,所以你的将会有所不同):

 DefaultWebService defaultWebService = new DefaultWebService(); String res = defaultWebService.getDefaultWebServiceHttpSoap11Endpoint().login("webservice","dadsadasdasd"); System.out.println(res);