corner imagecorner image
IDEPlatformPluginsDocs & SupportCommunityPartners

Разработка клиентов веб-служб JAX-WS

В данном руководстве возможности веб-служб среды IDE NetBeans используются для анализа веб-службы Проверки орфографии, после чего создается веб-клиент, взаимодействующий с этой службой. Клиент использует класс сервлетов и страницу JSP. Пользователь передает информацию сервлету со страницы JSP.

Содержание

Содержимое данной страницы относится к среде IDE NetBeans 6.9-7.1

Для работы с этим учебным курсом требуется программное обеспечение и ресурсы, перечисленные ниже.

Программное обеспечение или ресурс Требуемая версия
Среда IDE NetBeans Пакет загрузки Java EE
Комплект для разработчика на языке Java (JDK) версия 6 или версия 76
Внимание. Для среды IDE NetBeans 6.9 требуется JDK 6
Веб-сервер или сервер приложений, совместимый с Java EE Веб-сервер Tomcat 7.0
Сервер GlassFish, издание с открытым исходным кодом
Сервер Oracle WebLogic

Предостережение. В случае использования пакета JDK 6 необходим пакет JDK 6 Update 7 или более поздний.

Серверы Tomcat и GlassFish могут быть установлены при помощи дистрибутива "Web и Java EE" среды IDE NetBeans. Также можно воспользоваться страницей загрузок GlassFish Server или страницей загрузок Apache Tomcat.

Важно: Для проектов Java EE 6 требуются Tomcat 7.x, GlassFish Server 3.x или Oracle WebLogic Server 12c.

Ниже представлен внешний вид клиента со всеми данными, полученными от веб-службы:

Отчет по проверке орфографии

По окончании данного учебного курса вы обнаружите, что ваш единственный вклад в приложение состоит из предоставления текста на проверку, вызова веб-службы и вывода результата. Весь код, необходимый для взаимодействия с веб-службой и для передачи текста, создается в среде IDE автоматически. Веб-служба проверки орфографии позаботится обо всем остальном. Она определяет неправильно написанные слова и предоставляет список предлагаемых альтернатив.

Используемая в этом учебном курсе веб-служба проверки орфографии предоставлена CDYNE Corporation. Компания CDYNE занимается разработкой, продажей и поддержкой полного набора веб-служб расширения данных, качества данных и анализа данных, а также интеграцию решений по бизнес-информации и аналитике. Веб-служба проверки орфографии является одной из веб-служб, предоставляемых компанией CDYNE. Следует отметить, что стабильность приложений на основе одной или более веб-служб зависит от доступности и надежности веб-служб. Однако на странице Часто задаваемые вопросы компании CDYNE обозначена цель "100% доступности", и в случае "стихийного бедствия, террористического акта или другой катастрофы трафик веб-службы переводится на резервный центр данных компании". NetBeans благодарит CDYNE за возможность написания этого учебного курса и за помощь в его разработке.

Применение веб-службы проверки орфографии

Для использования веб-службы в сети (иначе называемого "потреблением веб-службы") необходимо создать клиент веб-службы. Для создания клиентов веб-службы среда IDE Netbeans предоставляет механизм создания клиента: мастер клиента веб-службы, в котором автоматически создается код для поиска веб-службы. Также предоставляются средства для разработки создаваемого клиента веб-службы – рабочая область, состоящая из узлов в окне "Проекты". Эти механизмы являются частью пакета EE в установке среды IDE Netbeans. Они доступны сразу после установки, дополнительные модули не требуются.

Создание клиента

Этот раздел посвящен работе с мастером для создания исходных объектов Java из файла WSDL веб-службы.

  1. Выберите пункт Файл > Создать проект (Ctrl-Shift-N в Windows и Linux, ⌘-Shift-N в MacOS). В разделе "Категории" выберите "Java Web". В области "Проекты" выберите "Веб-приложение". Нажмите кнопку "Далее". Назовите проект SpellCheckService и убедитесь, что в качестве целевого сервера указан соответствующий сервер. (Обратитесь к разделу "Начало работы" для получения дополнительных сведений). Оставьте значения остальных параметров по умолчанию и нажмите кнопку "Готово".
  2. В окне "Проекты" щелкните правой кнопкой мыши узел проекта SpellCheckService и выберите команду "Создать" > "Other". В мастере создания файла выберите "Веб-службы" > "Клиент веб-служб". В мастере "Клиент веб-службы" укажите URL-адрес веб-службы:

    http://wsf.cdyne.com/SpellChecker/check.asmx?wsdl

    Если компьютер защищен брандмауэром, то может потребоваться указать прокси-сервер, т.к. в противном случае загрузить файл WSDL будет невозможно. Чтобы указать прокси-сервер, нажмите в мастере кнопку "Настроить прокси". Открывается окно настроек среды IDE, в котором можно указать общий прокси-сервер для среды IDE.

  3. Название пакета указывать не следует. По умолчанию имя пакета класса клиента берется из WSDL. В данном случае это com.cdyne.ws.
  4. В окне "Проекты" в узле "Web Service References" должно быть представлено следующее:
    Окно "Проекты", в котором отображаются ссылки на веб-службы

В окне "Проекты" видно, что веб-служба под названием "check" сделала доступными для вашего приложения несколько операций "CheckTextBody" и "CheckTextBodyV2". В этих операциях строка проверяется на ошибки орфографии, и данные возвращаются для обработки клиентом. Версия службы V2 не требует проверки подлинности. В данном учебном курсе будет использоваться операция checkSoap.CheckTextBodyV2.

В узле Generated Sources показаны клиентские заглушки, автоматически созданные мастером создания клиента веб-службы JAX-WS.

Представление "Файлы" со структурой пакетов в узле "Сборка"

Разверните узел "WEB-INF" и нижележащий узел "wsdl". На экран будет выведена локальная копия файла WSDL с именем check.asmx.wsdl.

Окно "Проекты" с локальной копией файла WSDL и файла привязки в WEB-INF

URL-адрес файла WSDL, используемого для создания клиента, привязан к локальной копии файла WSDL в файле jax-ws-catalog.xml. Привязка к локальной копии имеет ряд преимуществ. Удаленная копия файла WSDL не обязательно должна быть доступна для выполнения клиента. Клиент выполняется быстрее, так как отсутствует потребность в анализе удаленного файла WSDL. Кроме того, упрощается переносимость. Дополнительные сведения приведены в статье на сайте DZone Усовершенствования переносимости и эффективности в клиентах JAX-WS, созданных с помощью среды IDE NetBeans 6.7.

Созданный файл привязки jax-ws-catalog

Разработка клиента

Существует много способов реализации клиента веб-службы. Файл WSDL веб-службы ограничивает тип данных, отправляемых в веб-службу, а также тип данных, получаемых в ответ. Однако файл WSDL не устанавливает ограничений ни на способ передачи требуемой информации, ни на компоненты пользовательского интерфейса. Формируемая ниже реализация клиента состоит из страницы JSP, позволяющей пользователю вводить текст для проверки, и сервлета, передающего текст в веб-службу и затем отображающего отчет с результатами.

Написание кода страницы JSP

Создаваемая нами страница JSP будет состоять из текстовой области, в которой пользователь может ввести текст, и из кнопки для передачи текста в веб-службу.

  1. В окне "Проекты" разверните узел "Web Pages" проекта SpellCheckService и дважды щелкните index.jsp для его открытия в редакторе исходного кода.
  2. Скопируйте следующий код и вставьте его в index.jsp поверх тегов <body>:
    <body>
      <form name="Test" method="post" action="SpellCheckServlet">
         <p>Введите текст для проверки:</p>
         <p>
         <p><textarea rows="7" name="TextArea1" cols="40" ID="Textarea1"></textarea></p>
         <p>
         <input type="submit" value="Проверка орфографии" name="spellcheckbutton">
      </form>
    </body>

    Описанный выше код указывает, что при нажатии кнопки передачи запроса содержимое области textarea передается методом POST в сервлет SpellCheckServlet.

Создание и написание кода для сервлета

В этом разделе описано создание сервлета, взаимодействующего с веб-службой. При этом код, выполняющий взаимодействие, предоставляется средой IDE. В результате необходимо работать только с бизнес-логикой, т.е. с подготовкой передаваемого текста и обработкой результата.

  1. Щелкните правой кнопкой мыши узел проекта SpellCheckService в окне "Проекты", выберите команду "Создать > Прочее", а затем "Веб > Сервлет". Нажмите кнопку "Далее". Откроется мастер создания сервлета.
  2. Назовите сервлет SpellCheckServlet и введите clientservlet в раскрывающемся списке "Пакет".
    Мастер создания сервлета с именем и пакетом сервлета
  3. Нажмите кнопку "Далее". Откроется панель настройки развертывания сервлета. Обратите внимание, что сопоставление URL-адреса для данного сервлета /SpellCheckServlet. Примите параметры по умолчанию и нажмите кнопку "Готово". Сервлет открывается в редакторе исходного кода.
    Вид в обозревателе
  4. Переведите курсор в редакторе исходного кода в тело метода processRequest и добавьте несколько новых строк прямо в верхней части метода.
  5. Щелкните правой кнопкой мыши область, созданную в предыдущем действии, и выберите "Вставить код > Вызвать операцию веб-службы". Выберите операцию checkSoap.CheckTextBodyV2 в диалоговом окне "Выбор вызываемой операции", как указано ниже:
    Окно "Проекты", в котором отображаются ссылки на веб-службы

    Нажмите кнопку "ОК".

    Примечание. Вместо вызова приведенного выше диалогового окна узел операции можно просто перетащить в редактор из окна "Проекты".

    В конце класса SpellCheckServlet виден закрытый метод вызова службы SpellCheckerV2 и возвращения объекта com.cdyne.ws.DocumentSummary.

    private DocumentSummary checkTextBodyV2(java.lang.String bodyText) {
    com.cdyne.ws.CheckSoap port = service.getCheckSoap();
    return port.checkTextBodyV2(bodyText);
    }

    Этого метода вполне достаточно для вызова операций веб-службы. Кроме того, в верхней части класса объявлены следующие строки кода:

    @WebServiceRef(wsdlLocation = "http://wsf.cdyne.com/SpellChecker/check.asmx?WSDL")
    private Check service;
  6. Замените блок try в методе processRequest() следующим кодом. Встроенные комментарии в коде объясняют назначение каждой строки.
    try {
        //Получение TextArea со страницы JSP
    String TextArea1 = request.getParameter("TextArea1");
    //Инициализация аргументов операции WS java.lang.String bodyText = TextArea1; //Обработка результата com.cdyne.ws.DocumentSummary doc = checkTextBodyV2(bodyText); String allcontent = doc.getBody(); //Из сводки полученного документа, //определить число неправильно написанных слов: int no_of_mistakes = doc.getMisspelledWordCount(); //Из полученной сводки документа, //определить массив неправильно написанных слов: List allwrongwords = doc.getMisspelledWord(); out.println("<html>"); out.println("<head>"); //Отобразить имя отчета как заголовок в строке заголовка браузера: out.println("<title>Отчет проверки правописания</title>"); out.println("</head>"); out.println("<body>"); //Отобразить имя отчета как заголовок в теле отчета: out.println("<h2><font color='red'>Spell Checker Report</font></h2>"); //Отобразить все содержимое (как с ошибками, так и без ошибок) между кавычками: out.println("<hr><b>Ваш текст:</b> \"" + allcontent + "\"" + "<p>"); //Для каждого массива слов с ошибками (по одному массиву на слово с ошибками), //определить слово с ошибками, количество предложений//и массив предложений. Далее выполняется отображение слова с ошибкой и числа возможных вариантов, //затем для массива вариантов, относящегося к текущему слову с ошибкой отображается //каждый вариант: for (int i = 0; i < allwrongwords.size(); i++) { String onewrongword = ((Words) allwrongwords.get(i)).getWord(); int onewordsuggestioncount = ((Words) allwrongwords.get(i)).getSuggestionCount(); List allsuggestions = ((Words) allwrongwords.get(i)).getSuggestions(); out.println("<hr><p><b>Wrong word:</b><font color='red'> " + onewrongword + "</font>"); out.println("<p><b>" + onewordsuggestioncount + " suggestions:</b><br>"); for (int k = 0; k < allsuggestions.size(); k++) { String onesuggestion = (String) allsuggestions.get(k); out.println(onesuggestion); } } //Отображение строки после каждого массива слов с ошибками: out.println("<hr>"); //Подведение итогов путем предоставления числа ошибок и их отображения: out.println("<font color='red'><b>Summary:</b> " + no_of_mistakes + " mistakes ("); for (int i = 0; i < allwrongwords.size(); i++) { String onewrongword = ((Words) allwrongwords.get(i)).getWord(); out.println(onewrongword); } out.println(")."); out.println("</font>"); out.println("</body>"); out.println("</html>"); } catch (Exception ex) { out.println("exception" + ex); } finally { out.close(); }
  7. Появятся панели ошибок и предупреждающие значки, указывающие на классы, которые не найдены. Чтобы исправить выражения импорта после вставки кода, либо нажмите Ctrl-Shift-I (⌘-Shift-I на Mac), или щелкните в любом месте правой клавишей, чтобы открыть контекстное меню, и выберите пункт "Исправить операторы импорта". Можно выбрать класс из списка классов List для импорта. Примите класс по умолчанию java.util.List. Ниже приведен полный список импортированных классов:
    import com.cdyne.ws.Check;
    import com.cdyne.ws.Words;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.List;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.xml.ws.WebServiceRef;

    Примечание.При получении предупреждения о том, что классы com.cdyne.* не найдены, не беспокойтесь. Эта проблема решается при сборке проекта, когда среда IDE анализирует файлы WSDL и обнаруживает классы.

    Следует отметить, что в приведенный выше код не входит обработка ошибок. Дополнительные сведения приведены в документе Закрепление материала на практике.

Развертывание клиента

Для сборки и выполнения веб-приложений в среде IDE используется сценарий сборки Ant. Этот сценарий сборки создается средой IDE на основе параметров, указанных при создании проекта. Точную настройку этих параметров можно выполнить в диалоговом окне проекта "Свойства проекта" (щелкните правой кнопкой мыши узел проекта в окне "Проекты" и выберите "Свойства").

  1. Щелкните правой кнопкой мыши узел проекта и выберите команду "Выполнить". Через некоторое время приложение должно развернуть и отобразить страницу JSP, код которой был написан в предыдущем разделе.
  2. Введите произвольный текст, убедившись, что часть текста написана с ошибками:
    Страница JSP с текстом для проверки
  3. Нажмите кнопку "Проверка орфографии" и посмотрите результат:
    Отчет по проверке орфографии с отмеченными ошибками

Асинхронные клиенты веб-служб

По умолчанию клиенты JAX-WS, созданные в среде IDE NetBeans, являются асинхронными. Синхронные клиенты посылают запрос в веб-службу и затем приостанавливают обработку до получения ответа. Однако в некоторых случаях необходимо продолжить выполнение каких-либо других действий, а не ожидать ответа. Например, в некоторых случаях для обработки запроса службой требуется значительное время. Клиенты веб-служб, которые продолжают работу без ожидания ответа службы, называются "асинхронными".

Асинхронные клиенты инициируют запрос службы и немедленно продолжают работу, не ожидая получения ответа. Службой обрабатывается запрос клиента, и по истечении некоторого времени отправляется ответ, который затем обрабатывается клиентом.

Асинхронные клиенты используют веб-службы как в режиме опроса, так и в режиме обратного вызова. При использовании метода опроса происходит вызов метода веб-службы и многократно запрашивается результат. Опрос занимает поток вызова и тем самым блокирует работу, что делает нежелательным его использование в приложениях с графическим интерфейсом пользователя. В режиме обратного вызова в момент вызова метода веб-службы в веб-службу передается обработчик обратного вызова. После получения результата вызывается метод обработчика handleResponse(). Данный режим подходит для приложений с графическим интерфейсом пользователя, поскольку при этом нет необходимости ожидать ответа. Например, если вызов осуществляется из обработчика событий графического интерфейса пользователя, то управление немедленно возвращается приложению, что позволяет предотвратить "зависание" интерфейса пользователя. Недостатком метода опроса является тот факт, что даже если ответ используется после получения, необходимо запросить его и узнать, что он получен.

В среде IDE NetBeans для добавления поддержки асинхронных клиентов веб-служб необходимо установить флажок в интерфейсе ссылок на веб-службы "Правка атрибутов веб-службы". Все прочие аспекты разработки клиентов совпадают со случаем синхронных клиентов, за исключением наличия методов опроса веб-служб и методов обратного вызова с ожиданием результата.

В остальной части данного раздела детально описывается создание графических интерфейсов Swing и внедрение в них асинхронных клиентов JAX-WS.

Создание формы Swing

В этом разделе описывается создание приложения Swing. Можно не выполнять разработку пользовательского графического интерфейса Swing самостоятельно, а просто загрузить предварительно разработанную форму JFrame и перейти к разделу Создание асинхронного клиента.

В клиент Swing передается набираемый на клавиатуре текст, который затем отправляется в службу, которая в свою очередь возвращает количество ошибок и список всех слов с ошибками. Кроме того, этот клиент также выводит каждое неправильно написанное слово и предлагает варианты его замены (слова с ошибками обрабатываются по одному).

Готовый клиент Swing

Создание клиента Swing:

  1. Создайте новый проект приложения Java. Назовите его AsynchSpellCheckClient НЕ создавайте класс Main для проекта.
  2. В представлении "Проекты" щелкните правой кнопкой мыши узел AsynchSpellCheckClient и выберите "Создать > Форма JFrame".
  3. Присвойте форме имя MainForm и разместите ее в пакете org.me.forms.
  4. После создания формы JFrame откройте свойства проекта. В категории "Выполнить" укажите MainForm в качестве главного класса.
    Окно "Свойства проекта", форма MainForm выбрана в качестве главного класса
  5. Откройте режим проектирования для MainForm.java в редакторе. Перетащите с палитры три элемента "панель прокрутки" на MainForm. Задайте положение и размер панелей прокрутки. В них будут размещены поля с набираемым текстом, который требуется проверить, слова с ошибками и предложения по замене очередного неправильно написанного слова.
  6. Перетащите пять текстовых полей на форму MainForm. Три их них разместите на панелях прокрутки. Измените их следующим образом:
    Текстовые поля
    Имя переменнойНа панели прокрутки?Доступно для редактирования?
    tfYourTextДаДа
    tfNumberMistakesНетНет
    tfWrongWordsДаНет
    tfWrongWord1НетНет
    tfSuggestions1ДаНет
  7. Перетащите индикатор выполнения на MainForm. Назовите переменную pbProgress.
  8. Перетащите две Кнопки на MainForm. Назовите первую кнопку btCheck и замените ее текст на "Проверить текст" или "Проверить правописание". Назовите вторую кнопку btNextWrongWord, измените ее текст на "Следующее слово с ошибкой" и сделайте ее неактивной.
  9. Перетащите несколько Ярлыков на MainForm, чтобы озаглавить ваше приложение и описать текстовые поля.

Настройте внешний вид JFrame в соответствии с предпочтениям и сохраните его. Затем добавьте функциональные возможности клиента веб-службы.

Включение асинхронных клиентов

Добавьте ссылки на веб-службу, как описано в разделе Создание клиента. Затем измените атрибуты веб-служб для включения асинхронных клиентов.

  1. В окне "Проекты" щелкните правой кнопкой мыши узел проекта AsynchSpellCheckClient и выберите команду "Создать" > "Прочее". В мастере создания файла выберите "Веб-службы" > "Клиент веб-службы". В мастере "Клиент веб-службы" укажите URL-адрес веб-службы:

    http://wsf.cdyne.com/SpellChecker/check.asmx?wsdl. Примите настройки по умолчанию и нажмите кнопку "Готово". Используйте ту же процедуру, что и в разделе Создание клиента, начиная с пункта 2.

  2. Раскройте узел "Ссылки на веб-службы" и щелкните правой кнопкой мыши службу check. Откроется контекстное меню.
    Контекстное меню службы "Check" в узле "Ссылки на веб-службы". Курсор наведен на меню "Правка атрибутов веб-службы"
  3. В контекстном меню выберите "Правка атрибутов веб-службы". Откроется диалоговое окно "Атрибуты веб-службы".
  4. Перейдите на вкладку "Настройка WSDL".
  5. Разверните узел "Операции типа порта". Разверните узел first CheckTextBodyV2 и выберите пункт "Включить асинхронный клиент".
    Диалоговое окно "Атрибуты веб-службы", показан вариант активации асинхронных клиентов для операции типа порта
  6. Нажмите кнопку "ОК". Диалоговое окно закроется, и появится предупреждение о том, что изменение атрибутов веб-службы приведет к обновлению узла клиента.
    Предупреждение о том, что обновление созданных классов и файлов WSDL окажет влияние на приложения, использующие созданные классы
  7. Нажмите кнопку "ОК". Окно предупреждения закроется, и узел клиента будет обновлен. Если развернуть узел check в узле "Ссылки на веб-службы", появятся два варианта работы CheckTextBody: "Опрос" и "Обратный вызов".
    Операции асинхронного клиента в окне "Проекты"

Теперь для приложения включены асинхронные клиенты веб-службы SpellCheck.

Добавление кода асинхронного клиента

Теперь, когда есть асинхронные операции веб-служб, добавьте асинхронную операцию к MainForm.java.

Добавление кода асинхронного клиента

  1. В MainForm перейдите к представлению исходного кода и добавьте следующий метод перед окончательной закрывающей скобкой.
    public void callAsyncCallback(String text){
                     
    }
  2. В окне "Проекты" разверните узел "Ссылки на веб-службу AsynchSpellCheckClient" и найдите операцию checkSoap.CheckTextBodyV2 [Asynch Callback].
  3. Перетащите операцию CheckTextBodyV2 [Asynch Callback] в пустое тело метода callAsyncCallback. Создается следующий блок try. Сравните этот сгенерированный код с кодом, который генерируется для синхронных клиентов.
    try { // Вызов операции веб-службы (асинхр. callback)
          com.cdyne.ws.Check service = new com.cdyne.ws.Check();
          com.cdyne.ws.CheckSoap port = service.getCheckSoap();
          // тут аргументы операции TODO initialize WS
          java.lang.String bodyText = "";
          javax.xml.ws.AsyncHandler<com.cdyne.ws.CheckTextBodyV2Response> asyncHandler = 
                  new javax.xml.ws.AsyncHandler<com.cdyne.ws.CheckTextBodyV2Response>() {
                public void handleResponse(javax.xml.ws.Response<com.cdyne.ws.CheckTextBodyV2Response> response) {
                      try {
                            // TODO process asynchronous response here
                            System.out.println("Результат = "+ response.get());
                      } catch(Exception ex) {
                            // TODO handle exception
                      }
                }
          };
          java.util.concurrent.Future<? extends java.lang.Object> result = port.checkTextBodyV2Async(bodyText, asyncHandler);
          while(!result.isDone()) {
                // do something
                Thread.sleep(100);
          }
          } catch (Exception ex) {
          // тут пользовательские исключения метки-манипулятора TODO
    }

    В этом коде, помимо вызова веб-службы, с помощью объекта AsynchHandler обрабатывается ответ от службы SpellCheck. В то же время объект Future проверяет, был ли возвращен результат, и приостанавливает работу потока до получения результата.

  4. Перейдите обратно к представлению проектирования. Дважды нажмите кнопку "Проверить правописание". При этом к кнопке автоматически добавляется действие ActionListener, и выполняется переход к представлению "Исходный код", причем курсор устанавливается в пустое тело метода btCheckActionPerformed.
  5. Добавьте следующий код к телу метода btCheckActionPerformed. Данный код получает текст, набираемый в поле tfYourText, отображает индикатор выполнения и сообщение "ожидание сервера", отключает кнопку btCheck и вызывает асинхронный метод с обратным вызовом.
    private void btCheckActionPerformed(java.awt.event.ActionEvent evt) {                                        
        String text = tfYourText.getText();
        pbProgress.setIndeterminate(true);
        pbProgress.setString("ожидание сервера");
        btCheck.setEnabled(false);
        callAsyncCallback(text);
    }
  6. В начале класса MainForm используйте закрытое поле ActionListener с именем nextWord. Данный ActionListener предназначено для кнопки "Следующее слово с ошибкой", которая добавляет одно слово в список неправильно написанных слов и отображает возможные варианты его исправления. Создается частное поле, поэтому если действие ActionListener уже было определено, можно отменить его регистрацию. В противном случае каждый раз при проверке нового текста потребуется добавлять дополнительный прослушивающий процесс, что в свою очередь приведет к многократному вызову actionPerformed(). Приложение будет работать некорректно.
    public class MainForm extends javax.swing.JFrame {
        
        private ActionListener nextWord;
        ...
  7. Замените весь метод callAsyncCallbackследующим кодом. Обратите внимание, что крайний снаружи блок tryудален. В нем нет необходимости, поскольку внутри метода добавлены более конкретные блоки try. Другие изменения в коде объяснены в комментариях к коду.
    public void callAsyncCallback(String text) {
    
            
        com.cdyne.ws.Check service = new com.cdyne.ws.Check();
        com.cdyne.ws.CheckSoap port = service.getCheckSoap();
        // тут инициализация аргументов операции WS
        java.lang.String bodyText = text;
    
        javax.xml.ws.AsyncHandler<com.cdyne.ws.CheckTextBodyV2Response> asyncHandler = new javax.xml.ws.AsyncHandler<com.cdyne.ws.CheckTextBodyV2Response>() {
    
            public void handleResponse(final javax.xml.ws.Response<com.cdyne.ws.CheckTextBodyV2Response> response) {
                SwingUtilities.invokeLater(new Runnable() {
    
                    public void run() {
    
                        try {
                            // Создание объекта DocumentSummary, содержащего ответ.
                            // Обратите внимание на то, что метод getDocumentSummary() вызывается из объекта Response, 
                            // в отличие от синхронного клиента, где он вызывается непосредственно из
                            // com.cdyne.ws.CheckTextBody
    com.cdyne.ws.DocumentSummary doc = response.get().getDocumentSummary();
    //Из полученного DocumentSummary, //извлекается и отображается количество неправильно написанных слов:
    final int no_of_mistakes = doc.getMisspelledWordCount(); String number_of_mistakes = Integer.toString(no_of_mistakes); tfNumberMistakes.setText(number_of_mistakes);
    // Проверка на наличие ошибок if (no_of_mistakes > 0 {
    //Из полученной сводки документа //извлекается массив слов с ошибками, если такие есть:
    final List<com.cdyne.ws.Words> allwrongwords = doc.getMisspelledWord();
    //Получение первого слова с ошибкой String firstwrongword = allwrongwords.get(0).getWord();
    //Сборка строки со всеми словами с ошибками, разделенными запятыми, и отображение этой строки в tfWrongWords
    StringBuilder wrongwordsbuilder = new StringBuilder(firstwrongword); for (int i = 1; i < allwrongwords.size(i++) { String onewrongword = allwrongwords.get(i).getWord(); wrongwordsbuilder.append(", "); wrongwordsbuilder.append(onewrongword); } String wrongwords = wrongwordsbuilder.toString(); tfWrongWords.setText(wrongwords);
    //Отображение первого слова с ошибкой tfWrongWord1.setText(firstwrongword);
    //Определение количества вариантов замены для слова с ошибкой int onewordsuggestioncount = allwrongwords.get(0).getSuggestionCount();
    //Проверка наличия вариантов замены. if (onewordsuggestioncount > 0) {
    //Создание списка вариантов замены для первого слова с ошибкой, и сборка из них строки. //Отображение строки с вариантами замены в поле tfSuggestions1
    List<String> allsuggestions = ((com.cdyne.ws.Words) allwrongwords.get(0).getSuggestions(); String firstsuggestion = allsuggestions.get(0); StringBuilder suggestionbuilder = new StringBuilder(firstsuggestion); for (int i = 1; i < onewordsuggestioncount; i++) { String onesuggestion = allsuggestions.get(i); suggestionbuilder.append(", "); suggestionbuilder.append(onesuggestion); } String onewordsuggestions = suggestionbuilder.toString(); tfSuggestions1.setText(onewordsuggestions); } else { // Для данной ошибки нет вариантов замены tfSuggestions1.setText("Нет вариантов замены"); } btNextWrongWord.setEnabled(true);
    // Проверка, назначено ли действие ActionListener для получения следующего слова с ошибкой и // вариантов его замены. Отмена регистрации (если действие зарегистрировано) так, чтобы в любой момент времени // был зарегистрирован только один детектор событий.
    if (nextWord != null) { btNextWrongWord.removeActionListener(nextWord); }
    // Определение ActionListener (экземпляр создан ранее как частное поле) nextWord = new ActionListener() {
    //Инициализация переменной для работы с индексом перечня allwrongwords (слов с ошибками) int wordnumber = 1; public void actionPerformed(ActionEvent e) { if (wordnumber < no_of_mistakes) {
    // получить слово с ошибкой в позиции индекса wordnumber в списке allwrongwords String onewrongword = allwrongwords.get(wordnumber).getWord();
    //следующая часть аналогична коду для первого слова с ошибкой
    tfWrongWord1.setText(onewrongword); int onewordsuggestioncount = allwrongwords.get(wordnumber).getSuggestionCount(); if (onewordsuggestioncount > 0) { List<String> allsuggestions = allwrongwords.get(wordnumber).getSuggestions(); String firstsuggestion = allsuggestions.get(0); StringBuilder suggestionbuilder = new StringBuilder(firstsuggestion); for (int j = 1; j < onewordsuggestioncount; j++) { String onesuggestion = allsuggestions.get(j); suggestionbuilder.append(", "); suggestionbuilder.append(onesuggestion); } String onewordsuggestions = suggestionbuilder.toString(); tfSuggestions1.setText(onewordsuggestions); } else { tfSuggestions1.setText("No suggestions"); }
    //увеличение i на 1 wordnumber++;
    } else { // Слов с ошибками не осталось! Установка неактивного состояния для кнопки "следующее слово" // Активация кнопки проверки btNextWrongWord.setEnabled(false); btCheck.setEnabled(true); } } };
    // Регистрация ActionListener btNextWrongWord.addActionListener(nextWord);
    } else { // В тексте нет ошибок // Включить кнопку "Проверка" tfWrongWords.setText("Нет слов с ошибками"); tfSuggestions1.setText("Нет вариантов замены"); tfWrongWord1.setText("--"); btCheck.setEnabled(true); } } catch (Exception ex) { ex.printStackTrace(); }
    // Очистка индикатора выполнения pbProgress.setIndeterminate(false); pbProgress.setString(""); } }); } }; java.util.concurrent.Future result = port.checkTextBodyV2Async(bodyText, asyncHandler); while (!result.isDone()) { try {
    //Отображение сообщения о том, что приложение ожидает ответа сервера tfWrongWords.setText("Ожидание..."); Thread.sleep(100); } catch (InterruptedException ex) { Logger.getLogger(MainForm.class.getName()).log(Level.SEVERE, null, ex); } } }
  8. Нажмите Ctrl-Shift-I (⌘-Shift-I на Mac) и исправьте импорт. Это приведет к добавлению следующих операторов импорта:
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.List;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.SwingUtilities;

Теперь приложение можно собрать и запустить. По всей вероятности, однако, уследить за событиями в течение ожидания ответа от сервера не удастся, поскольку служба работает достаточно быстро.

Закрепление материала на практике

Теперь, после завершения создания клиента веб-службы в среде IDE, пришло время приобрести дополнительные навыки и сделать из приложения то, ради чего оно задумывалось. Ниже приведены две подходящие для начала задачи.

  • Добавление в сервлет кода обработки ошибок.
  • Переработка клиента таким образом, чтобы пользователь мог взаимодействовать с возвращенными из веб-службы данными..


Дополнительные сведения

Дополнительные сведения о разработке приложений для Java EE в среде IDE NetBeans приведены в следующих материалах:

Чтобы отправить комментарии и предложения, получить поддержку и информацию о последних разработках среды IDE Netbeans в области возможностей разработки для Java EE, присоединитесь к списку рассылки .