SOAP веб-сервисы на Java можно разрабатывать различными способами. Мы узнали о JAX-WS SOAP веб-сервисах в нашем последнем уроке, сегодня мы узнаем, как создать SOAP веб-сервис и программу его клиента с использованием Eclipse. Здесь мы не будем использовать JAX-WS, мы будем использовать Apache Axis, который интегрирован в Eclipse и предоставляет быстрый и простой способ преобразования приложения в веб-сервис Java и создания клиентских заглушек с тестовой JSP-страницей для тестирования.
SOAP веб-сервисы на Java
Я использую Eclipse Mars Release (4.5.0) для этого урока, но я думаю, что эти шаги будут работать и с более старыми версиями Eclipse. Также убедитесь, что вы добавили Apache Tomcat или любой другой контейнер сервлетов в качестве сервера в Eclipse. Давайте начнем с нашей реализации веб-сервиса Eclipse сейчас.
Пример SOAP веб-сервиса
Давайте начнем с нашего примера веб-сервиса SOAP в Eclipse. Прежде всего мы создадим простой Динамический веб-проект в Eclipse, который будет содержать бизнес-логику нашего приложения. Нажмите на кнопку “Next” выше, и вы перейдете на следующую страницу, где сможете указать имя вашего веб-проекта и Целевое средство выполнения. Обратите внимание, что я использую Apache Tomcat 8, но вы также можете использовать любой другой стандартный контейнер сервлетов.
Нажмите “Next”, и вам будет предложено указать “Корневой контекст” и местоположение каталога содержимого. Вы можете оставить их значения по умолчанию.
Нажмите “Finish”, и Eclipse создаст каркас проекта для вас. Давайте начнем с нашей бизнес-логики. Для нашего примера мы хотели бы опубликовать веб-сервис, который можно использовать для добавления/удаления/получения объекта. Поэтому первый шаг – создать модельный бин.
package com.journaldev.jaxws.beans;
import java.io.Serializable;
public class Person implements Serializable{
private static final long serialVersionUID = -5577579081118070434L;
private String name;
private int age;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString(){
return id+"::"+name+"::"+age;
}
}
Вот простой Java Bean выше. Мы реализуем интерфейс Serializable
, поскольку собираемся передавать его по сети. Также мы предоставили реализацию метода toString
, который будет использоваться при выводе этого объекта на стороне клиента. Следующим шагом будет создание сервисных классов: у нас будет интерфейс PersonService
и его простая реализация PersonServiceImpl
.
package com.journaldev.jaxws.service;
import com.journaldev.jaxws.beans.Person;
public interface PersonService {
public boolean addPerson(Person p);
public boolean deletePerson(int id);
public Person getPerson(int id);
public Person[] getAllPersons();
}
Вот реализация сервисного класса, где мы используем Map для хранения объектов Person в качестве источника данных. В реальном мире программирования мы бы предпочли сохранять их в таблицы базы данных.
package com.journaldev.jaxws.service;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.journaldev.jaxws.beans.Person;
public class PersonServiceImpl implements PersonService {
private static Map<Integer,Person> persons = new HashMap<Integer,Person>();
@Override
public boolean addPerson(Person p) {
if(persons.get(p.getId()) != null) return false;
persons.put(p.getId(), p);
return true;
}
@Override
public boolean deletePerson(int id) {
if(persons.get(id) == null) return false;
persons.remove(id);
return true;
}
@Override
public Person getPerson(int id) {
return persons.get(id);
}
@Override
public Person[] getAllPersons() {
Set<Integer> ids = persons.keySet();
Person[] p = new Person[ids.size()];
int i=0;
for(Integer id : ids){
p[i] = persons.get(id);
i++;
}
return p;
}
}
Это весь наш бизнес-логика, поскольку мы будем использовать это в веб-сервисе, здесь нет смысла создавать веб-страницы. Обратите внимание, что у нас нет ссылок на какие-либо классы веб-сервисов в вышеуказанном коде.
SOAP-веб-сервисы в Java с использованием Eclipse
Как только наша бизнес-логика готова, следующим шагом будет использование Eclipse для создания веб-сервисного приложения из неё. Создайте новый проект и выберите мастер веб-сервисов. Нажмите кнопку Далее, и вы попадете на страницу, где нужно будет указать детали веб-сервиса и его клиента. Это самая важная страница при создании веб-сервиса. Убедитесь, что выбираете тип “Веб-сервис” как “Создание веб-сервиса Java Bean снизу вверх”, потому что мы реализуем его снизу вверх. Существует два способа создания веб-сервиса:
- Создание контракта в конце или подход снизу вверх: В этом подходе мы сначала создаем реализацию, а затем генерируем из неё файл WSDL. Наша реализация подходит под эту категорию.
- Создание контракта в начале или подход сверху вниз: В этом подходе мы сначала создаем контракт веб-сервиса, то есть файл WSDL, а затем создаем его реализацию.
В реализации службы предоставьте полный классифицированный путь к классу реализации
PersonServiceImpl
. Убедитесь, что вы переместили ползунок в службу и тип клиента на левую сторону, чтобы он мог создать клиентскую программу, а также интерфейс для тестирования нашей веб-службы. Проверьте конфигурации в реализации веб-службы, вы должны предоставить правильные детали для времени выполнения сервера, времени выполнения веб-службы и проекта службы. Обычно они автоматически заполняются, и вам не нужно вносить здесь изменения. Для конфигураций клиента вы можете указать имя клиентского проекта, как вам удобно. Я оставил его по умолчанию как SOAPExampleClient
. Если вы нажмете на ссылку для времени выполнения веб-службы, вы получите различные варианты, как показано на изображении ниже. Однако я оставил его как значение по умолчанию. Нажмите кнопку “Далее”, и затем вы сможете выбрать методы, которые вы хотите выставить веб-службой. Вы также сможете выбрать стиль веб-службы как документ или буквально. Вы можете изменить имя документа WSDL, но лучше иметь его с именем класса реализации, чтобы избежать путаницы позже.
Нажмите кнопку “Далее”, и у вас появится страница запуска сервера, нажмите кнопку “Запустить сервер”, а затем кнопка “Далее” станет активной.
Нажмите кнопку “Далее”, и у вас появится страница для запуска “Исследователя веб-служб”.
Нажмите кнопку “Запуск”, и откроется новое окно в браузере, где вы сможете протестировать свою веб-службу перед переходом к части клиентского приложения. Это выглядит как на изображении ниже для нашего проекта.
Здесь мы можем провести некоторые тесты для проверки работоспособности, но для нашего простого приложения я готов перейти к созданию клиентского приложения. Нажмите кнопку “Далее” во всплывающем окне веб-служб Eclipse, и у вас появится страница для выбора исходной папки для клиентского приложения.
Нажмите кнопку “Далее”, и у вас появятся различные варианты для выбора в качестве средства тестирования. Я собираюсь использовать JAX-RPC JSPs, чтобы клиентское приложение создало страницу JSP, которую мы сможем использовать.
Обратите внимание на методы
getEndpoint()
и setEndpoint(String)
, добавленные, чтобы мы могли получить URL конечной точки веб-службы и установить его в другой URL в случае перемещения сервера. Нажмите кнопку “Готово”, и Eclipse создаст клиентский проект в вашем рабочем пространстве, также запустит тестовую страницу JSP клиента, как показано ниже. Вы можете скопировать URL и открыть его в любом браузере по вашему выбору. Давайте протестируем некоторые из предоставленных нами служб и посмотрим результат.
Тестирование веб-сервисов SOAP Eclipse
-
getAllPersons
Обратите внимание, что сведения о лицах не выводятся в разделе результатов, потому что это автогенерируемый код, и нам немного нужно его переработать, чтобы получить желаемый результат. Откройте файл Result.jsp в клиентском проекте, и вы увидите, что для генерации вывода результата он использует оператор switch case. Для метода getAllPersons() это был случай 42 в моем случае. Обратите внимание, что в вашем случае это может быть совершенно иное значение. Я просто изменил код для случая 42, как показано ниже.
case 42: gotMethod = true; com.journaldev.jaxws.beans.Person[] getAllPersons42mtemp = samplePersonServiceImplProxyid.getAllPersons(); if(getAllPersons42mtemp == null){ %> <%=getAllPersons42mtemp %> <% }else{ String tempreturnp43 = null; if(getAllPersons42mtemp != null){ java.util.List<com.journaldev.jaxws.beans.Person> listreturnp43= java.util.Arrays.asList(getAllPersons42mtemp); //tempreturnp43 = listreturnp43.toString(); for(com.journaldev.jaxws.beans.Person p : listreturnp43){ int id = p.getId(); int age = p.getAge(); String name=p.getName(); %> <%=id%>::<%=name %>::<%=age %> <% } } } break;
После этого мы получаем следующий вывод, обратите внимание, что здесь Eclipse выполняет горячее развертывание, поэтому мне не нужно было перезагружать мое приложение.
Таким образом, кажется, что наш веб-сервис и клиентские приложения работают нормально, уделите время изучению сгенерированных Eclipse клиентских заглушек, чтобы лучше понять.
WSDL и конфигурации SOAP веб-сервиса
Наконец, вы заметите, что файл WSDL сгенерирован в проекте веб-сервиса, как показано ниже. Код PersonServiceImpl.wsdl:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="https://service.jaxws.journaldev.com" xmlns:apachesoap="https://xml.apache.org/xml-soap" xmlns:impl="https://service.jaxws.journaldev.com" xmlns:intf="https://service.jaxws.journaldev.com" xmlns:tns1="https://beans.jaxws.journaldev.com" xmlns:wsdl="https://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="https://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="https://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)-->
<wsdl:types>
<schema elementFormDefault="qualified" targetNamespace="https://service.jaxws.journaldev.com" xmlns="https://www.w3.org/2001/XMLSchema">
<import namespace="https://beans.jaxws.journaldev.com"/>
<element name="addPerson">
<complexType>
<sequence>
<element name="p" type="tns1:Person"/>
</sequence>
</complexType>
</element>
<element name="addPersonResponse">
<complexType>
<sequence>
<element name="addPersonReturn" type="xsd:boolean"/>
</sequence>
</complexType>
</element>
<element name="deletePerson">
<complexType>
<sequence>
<element name="id" type="xsd:int"/>
</sequence>
</complexType>
</element>
<element name="deletePersonResponse">
<complexType>
<sequence>
<element name="deletePersonReturn" type="xsd:boolean"/>
</sequence>
</complexType>
</element>
<element name="getPerson">
<complexType>
<sequence>
<element name="id" type="xsd:int"/>
</sequence>
</complexType>
</element>
<element name="getPersonResponse">
<complexType>
<sequence>
<element name="getPersonReturn" type="tns1:Person"/>
</sequence>
</complexType>
</element>
<element name="getAllPersons">
<complexType/>
</element>
<element name="getAllPersonsResponse">
<complexType>
<sequence>
<element maxOccurs="unbounded" name="getAllPersonsReturn" type="tns1:Person"/>
</sequence>
</complexType>
</element>
</schema>
<schema elementFormDefault="qualified" targetNamespace="https://beans.jaxws.journaldev.com" xmlns="https://www.w3.org/2001/XMLSchema">
<complexType name="Person">
<sequence>
<element name="age" type="xsd:int"/>
<element name="id" type="xsd:int"/>
<element name="name" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
</schema>
</wsdl:types>
<wsdl:message name="addPersonResponse">
<wsdl:part element="impl:addPersonResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getAllPersonsResponse">
<wsdl:part element="impl:getAllPersonsResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="deletePersonResponse">
<wsdl:part element="impl:deletePersonResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="addPersonRequest">
<wsdl:part element="impl:addPerson" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getPersonResponse">
<wsdl:part element="impl:getPersonResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getPersonRequest">
<wsdl:part element="impl:getPerson" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="deletePersonRequest">
<wsdl:part element="impl:deletePerson" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getAllPersonsRequest">
<wsdl:part element="impl:getAllPersons" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="PersonServiceImpl">
<wsdl:operation name="addPerson">
<wsdl:input message="impl:addPersonRequest" name="addPersonRequest">
</wsdl:input>
<wsdl:output message="impl:addPersonResponse" name="addPersonResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="deletePerson">
<wsdl:input message="impl:deletePersonRequest" name="deletePersonRequest">
</wsdl:input>
<wsdl:output message="impl:deletePersonResponse" name="deletePersonResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getPerson">
<wsdl:input message="impl:getPersonRequest" name="getPersonRequest">
</wsdl:input>
<wsdl:output message="impl:getPersonResponse" name="getPersonResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllPersons">
<wsdl:input message="impl:getAllPersonsRequest" name="getAllPersonsRequest">
</wsdl:input>
<wsdl:output message="impl:getAllPersonsResponse" name="getAllPersonsResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="PersonServiceImplSoapBinding" type="impl:PersonServiceImpl">
<wsdlsoap:binding style="document" transport="https://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="addPerson">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="addPersonRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="addPersonResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="deletePerson">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="deletePersonRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="deletePersonResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getPerson">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getPersonRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getPersonResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllPersons">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getAllPersonsRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getAllPersonsResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="PersonServiceImplService">
<wsdl:port binding="impl:PersonServiceImplSoapBinding" name="PersonServiceImpl">
<wsdlsoap:address location="https://localhost:8080/SOAPExample/services/PersonServiceImpl"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Если вы откроете его в режиме дизайна в Eclipse, он будет выглядеть как на изображении ниже. Вы также можете получить доступ к файлу WSDL веб-сервиса через браузер, добавив ?wsdl к конечной точке веб-сервиса.
Вы также заметите, что web.xml изменен для использования Apache Axis в качестве фронт-контроллера для веб-сервиса.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>SOAPExample</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<display-name>Apache-Axis Servlet</display-name>
<servlet-name>AxisServlet</servlet-name>
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/servlet/AxisServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet>
<display-name>Axis Admin Servlet</display-name>
<servlet-name>AdminServlet</servlet-name>
<servlet-class>org.apache.axis.transport.http.AdminServlet</servlet-class>
<load-on-startup>100</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AdminServlet</servlet-name>
<url-pattern>/servlet/AdminServlet</url-pattern>
</servlet-mapping>
</web-app>
Ниже показан веб-сервис и клиентский проект со всеми автоматически сгенерированными заглушками и JSP-страницами для тестирования веб-сервиса.
Вот и все для примера soap-веб-сервисов на Java с использованием Eclipse, как вы можете видеть, что все сложное было сделано Eclipse автоматически, и все наше внимание было сосредоточено на написании бизнес-логики для нашего веб-сервиса.
Source:
https://www.digitalocean.com/community/tutorials/soap-webservices-in-java-example-eclipse