2013-04-11 3 views
97

Я относительный новичок в мире webservices, и мои исследования, похоже, смутили меня больше, чем просветили меня, моя проблема в том, что мне была предоставлена ​​библиотека (jar), которую я должен расширить с помощью некоторых функций webservice.Как сделать вызов веб-службы SOAP из класса Java?

Эта библиотека будет доступна другим разработчикам, а среди классов в банке будут классы, которые имеют метод, который вызывает веб-сервис (который по существу устанавливает атрибут класса, выполняет некоторую бизнес-логику, например, хранение объекта в db и т. д. и отправляет обратно объект с этими изменениями). Я хочу сделать вызов этой службы максимально простым, надеюсь, так же просто, чтобы разработчик, использующий класс, только должен был сделать.

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

Я изучаю JAX-WS для использования на сервере, но мне кажется, что мне не нужно, чтобы создать wsimport на сервере, ни wsimport на клиенте, так как я знаю, что оба имеют классов, мне просто нужно некоторое взаимодействие между классами, которые используются как на сервере, так и на клиенте. Как вы думаете, имеет смысл делать веб-сервис и вызов в классе?

+0

Ваш вопрос немного неясно.Метод, который вы хотите создать, будет (1) получить объект от веб-службы; (2) немного работать с объектом; и (3) отправить его обратно в веб-службу. Это оно? – acdcjunior

+0

Нет, объект будет создан в клиенте, он будет отправлен в ws в вызове, ws установит переменную, например currentTime, выполнит некоторую бизнес-логику, чтобы сохранить ее в db, а затем отправил объект возвращается клиенту с установленным текущим временем. Надеюсь, я объяснил себе немного лучше. Спасибо. – jpz

ответ

222

Я понимаю, что ваша проблема сводится к как вызвать веб-службу SOAP (JAX-WS) с Java и получить ее возвращаемый объект. В этом случае у вас есть два возможных подхода:

  1. Создайте классы Java через wsimport и используйте их; или
  2. Создание клиента SOAP, что:
    1. Сериализует параметры сервиса в XML;
    2. Вызывает метод Интернета с помощью HTTP-манипуляции; и
    3. Анализ возвращаемого ответа XML обратно в объект.


О первом подходе (с использованием wsimport):

Я вижу, у вас уже есть услуги (предприятие или другой) бизнес-класс, и это факт, что wsimport генерирует целый новый набор классов (это как-то дубликаты классов, которые у вас уже есть).

Я боюсь, однако, в этом случае, вы можете только либо:

  • Adapt (отредактировать) wsimport сгенерированный код, чтобы сделать его использовать ваши бизнес-класса (это сложно и как-то не стоит того - помните каждый раз, когда изменения WSDL, вам придется регенерировать и читать код); или
  • Снять и использовать созданные wsimport классы. (В этом решении бизнес-код может «использовать» созданные классы как службу из другого архитектурного уровня.)

О втором подходе (создать свой собственный клиент SOAP):

Для реализации второго подхода, вам придется:

  1. сделать вызов:
    • Используйте API-интерфейс SAAJ (SOAP with Attachments API for Java) (см. Ниже, он поставляется с Java SE 1.6 или выше) для совершения вызовов; или
    • Вы также можете сделать это через java.net.HttpUrlconnection (и некоторые java.io).
  2. Включите объекты в и обратно из XML:
    • использовать ОХМ (Object картированию XML) структуры, такие как JAXB для сериализации/десериализации XML из/в объекты
    • Или, если вы необходимо вручную создать/проанализировать XML (это может быть лучшим решением, если полученный объект немного отличается от отправленного).

Создание клиента SOAP с помощью классического java.net.HttpUrlConnection не так сложно (но не так просто либо), и вы можете найти в this link очень хорошей отправной кода.

Я рекомендую использовать рамки SAAJ:

SOAP с вложениями API для Java (SAAJ) используется в основном для работы непосредственно с SOAP-сообщениями запрос/ответ, который происходит за кулисами в любом веб-службы API. Это позволяет разработчикам напрямую отправлять и получать мыльные сообщения вместо использования JAX-WS.

См. Ниже рабочий пример (запустите его!) Вызова веб-службы SOAP с использованием SAAJ. Он называет 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; 
    } 

} 

Об использовании JAXB для сериализации/десериализации, очень легко найти информацию об этом. Вы можете начать здесь: http://www.mkyong.com/java/jaxb-hello-world-example/.

+0

Как установить версию мыла, используя метод, упомянутый выше? – Redone

+0

Я смог использовать ваш метод, и он работал, когда я использовал ваш URI, но для моего собственного запроса SOAP я получаю ответ, в котором ни одно из значений не отображается как ожидалось, то есть '' ''. Как вы можете видеть, элемент закрыт, и из WS не создается никакой информации. – santafebound

+0

'GetInfoByCity' - это' 503Service Unavailable', это видно. :( –

1

Или просто используйте Apache CXF's 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); 

Существует даже Maven плагин, который генерирует источники: https://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html