Как сделать вызов веб-службы SOAP из classа Java?

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

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

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

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

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

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

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

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

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

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

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

Чтобы реализовать второй подход, вам необходимо:

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

Создание SOAP-клиента с использованием classического java.net.HttpUrlConnection не так уж сложно (но не так просто), и вы можете найти в этой ссылке очень хороший стартовый код.

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

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

Ниже приведен рабочий пример (запустите его!) Вызова веб-службы SOAP с помощью SAAJ. Он вызывает этот веб-сервис .

 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:     100    */ // 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/ .

Или просто используйте wsdl2java для Apache CXF для создания объектов, которые вы можете использовать.

Он включен в бинарный пакет, который вы можете скачать со своего веб-сайта. Вы можете просто запустить команду следующим образом:

 $ ./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

Примечание. Если вы создаете источники с использованием CXF и IDEA, вы можете посмотреть на это: https://stackoverflow.com/a/46812593/840315

  • Что такое «веб-сервис» на простом английском языке?
  • jQuery Ajax звонки на веб-службу кажутся синхронными
  • Добавление веб-службы в уже ansible Java-проект
  • максимальная длина HTTP GET-запроса?
  • Сертификат клиента SSL в Maven
  • Понимание CORS
  • Веб-служба и служба WCF
  • Spring, Jackson и Customization (например, CustomDeserializer)
  • Не удалось загрузить исключение файла или сборки
  • Как я могу подключить iPhone и веб-службу и получить данные XML?
  • Веб-сервис Java без сервера веб-приложений
  • Interesting Posts

    Объединение значений из связанных строк в одно конкатенированное строковое значение

    Используйте все громкоговорители 5.1 с источником звука 2.1

    Получить TFS, чтобы игнорировать папку моих пакетов

    Как инициализировать List для заданного размера (в отличие от емкости)?

    Как узнать настройки порта и завершения порта для перенаправления портов?

    AngularJS Несколько ng-приложений на странице

    HTML5 Video не работает с тегом AngularJS ng-src

    java.lang.StackOverflowError при использовании RegEx для синтаксического анализа больших строк

    Когда использовать val или def в чертах Scala?

    Префикс для всех селекторов для twitter bootstrap меньше

    Почему сопоставитель строк по умолчанию не поддерживает переходную последовательность?

    Файл PCH в Xcode 6

    SwipeRefreshLayout + WebView, когда позиция прокрутки находится наверху

    Создайте список простых чисел до определенного числа

    Что такое «N» версии Windows 8?

    Давайте будем гением компьютера.