2013-04-11 46 views
97

Tôi tương đối mới với thế giới web và nghiên cứu của tôi dường như đã làm tôi bối rối hơn là khai sáng cho tôi, vấn đề của tôi là tôi đã được cung cấp một thư viện (jar) mà tôi phải mở rộng với một số chức năng webservice.Làm thế nào để thực hiện một cuộc gọi dịch vụ Web SOAP từ lớp Java?

Thư viện này sẽ được chia sẻ với các nhà phát triển khác, và trong số các lớp trong jar sẽ là các lớp có phương thức gọi một webservice (về cơ bản đặt thuộc tính của lớp, thực hiện một số logic nghiệp vụ, như lưu trữ đối tượng trong một db, vv và gửi lại đối tượng với những sửa đổi đó). Tôi muốn thực hiện cuộc gọi đến dịch vụ này đơn giản nhất có thể, hy vọng đơn giản để nhà phát triển sử dụng lớp chỉ cần thực hiện.

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

Tôi đã học JAX-WS để sử dụng trên máy chủ nhưng dường như với tôi rằng tôi không cần phải tạo ra một wsimport trong máy chủ lẫn wsimport trên máy khách, vì tôi biết rằng cả hai đều có các lớp, tôi chỉ cần một số tương tác giữa các lớp được chia sẻ trong cả máy chủ và máy khách. Làm thế nào để bạn nghĩ rằng làm cho tinh thần để làm các webservice và các cuộc gọi trong lớp học?

+0

câu hỏi của bạn là một chút không rõ ràng.Phương thức bạn muốn tạo sẽ (1) lấy đối tượng từ dịch vụ web; (2) làm việc với đối tượng một chút; và (3) đăng nó trở lại dịch vụ web. Là nó? – acdcjunior

+0

Không, đối tượng sẽ được tạo trong máy khách, nó sẽ được gửi đến các w trong cuộc gọi, các ws sẽ thiết lập một biến, ví dụ currentTime, làm một số logic nghiệp vụ như lưu trữ nó trong một db, và sau đó gửi đối tượng quay lại máy khách với currentTime hiện đã được đặt. Hy vọng tôi giải thích bản thân mình tốt hơn một chút. Cảm ơn bạn. – jpz

Trả lời

222

Tôi hiểu vấn đề của bạn sẽ giảm xuống cách gọi dịch vụ web SOAP (JAX-WS) từ Java và nhận đối tượng trả về. Trong trường hợp đó, bạn có hai cách tiếp cận có thể có:

  1. Tạo các lớp Java qua wsimport và sử dụng chúng; hoặc
  2. Tạo ứng dụng khách SOAP:
    1. Nối tiếp các tham số của dịch vụ thành XML;
    2. Gọi phương thức web thông qua thao tác HTTP; và
    3. Phân tích cú pháp phản hồi XML trả về thành đối tượng.


Về phương pháp tiếp cận đầu tiên (sử dụng wsimport):

tôi thấy bạn đã có các dịch vụ (tổ chức hoặc khác) các lớp học kinh doanh, và đó là một thực tế là các wsimport tạo một tập hợp các lớp hoàn toàn mới (bằng cách nào đó sao chép các lớp bạn đã có).

Tôi sợ, tuy nhiên, trong trường hợp này, bạn có thể chỉ một trong hai:

  • Thích ứng (chỉnh sửa) wsimport mã được tạo để làm cho nó sử dụng lớp doanh nghiệp của bạn (đây là khó khăn và bằng cách nào đó không giá trị nó - ghi nhớ mọi thay đổi WSDL, bạn sẽ phải tạo lại và đọc mã); hoặc
  • Hãy từ bỏ và sử dụng các lớp học được tạo ra wsimport. (Trong giải pháp này, mã doanh nghiệp của bạn có thể "sử dụng" các lớp được tạo ra như một dịch vụ từ một lớp kiến ​​trúc khác.)

Về cách tiếp cận thứ hai (tạo khách hàng SOAP tùy chỉnh của bạn):

Để thực hiện phương pháp thứ hai, bạn sẽ phải:

  1. Hãy gọi:
    • Sử dụng khung công tác SAAJ (SOAP với tệp đính kèm API cho Java) (xem bên dưới, nó được vận chuyển với Java SE 1.6 trở lên) để thực hiện cuộc gọi; hoặc
    • Bạn cũng có thể thực hiện thông qua java.net.HttpUrlconnection (và một số xử lý java.io).
  2. Xoay đối tượng vào và trở lại từ XML:
    • Sử dụng một OXM (Object để Mapping XML) khuôn khổ như JAXB serialize/deserialize XML từ/thành các đối tượng
    • Hoặc, nếu bạn phải, tự tạo/phân tích cú pháp XML (điều này có thể là giải pháp tốt nhất nếu đối tượng nhận được chỉ khác biệt một chút so với gửi đi).

Tạo một khách hàng SOAP sử dụng cổ điển java.net.HttpUrlConnection không phải là khó (nhưng không đơn giản như một trong hai), và bạn có thể tìm thấy trong this link mã khởi đầu rất tốt.

tôi khuyên bạn nên sử dụng khuôn khổ SAAJ:

SOAP với Attachments API cho Java (SAAJ) được sử dụng chủ yếu để đối phó trực tiếp với SOAP thông điệp request/response mà xảy ra đằng sau hậu trường trong bất cứ Dịch vụ Web API. Nó cho phép các nhà phát triển trực tiếp gửi và nhận tin nhắn xà phòng thay vì sử dụng JAX-WS.

Xem bên dưới ví dụ hoạt động (chạy nó!) Của cuộc gọi dịch vụ web SOAP bằng SAAJ. Nó gọi this web service.

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; 
    } 

} 

Giới thiệu về việc sử dụng JAXB để tuần tự hóa/deserializing, rất dễ dàng để tìm thông tin về nó. Bạn có thể bắt đầu tại đây: http://www.mkyong.com/java/jaxb-hello-world-example/.

+0

Làm cách nào để đặt phiên bản xà phòng bằng phương pháp được đề cập ở trên? – Redone

+0

Tôi đã có thể sử dụng phương pháp của bạn và nó hoạt động khi tôi sử dụng URI của bạn nhưng với yêu cầu SOAP của riêng tôi, tôi nhận được một phản hồi mà không có giá trị nào được hiển thị như mong đợi, nghĩa là '' ''. Như bạn có thể thấy, phần tử được đóng lại và không có thông tin nào được tạo ra từ WS. – santafebound

+0

'GetInfoByCity' là' 503Service Unavailable', có vẻ như vậy. :( –

1

Hoặc chỉ sử dụng Apache CXF's wsdl2java để tạo các đối tượng bạn có thể sử dụng.

Nó được bao gồm trong gói nhị phân bạn có thể tải xuống từ trang web của họ. Bạn chỉ có thể chạy một lệnh như thế này:

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

Nó sử dụng wsdl để tạo ra đối tượng mà bạn có thể sử dụng như thế này (tên đối tượng cũng được nắm lấy từ wsdl, vì vậy bạn sẽ khác một chút):

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

Thậm chí còn có một Maven plug-in mà tạo ra các nguồn: https://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html

Các vấn đề liên quan