SOAP веб-сервисы в Java с примером, используя Eclipse

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 снизу вверх”, потому что мы реализуем его снизу вверх. Существует два способа создания веб-сервиса:

  1. Создание контракта в конце или подход снизу вверх: В этом подходе мы сначала создаем реализацию, а затем генерируем из неё файл WSDL. Наша реализация подходит под эту категорию.
  2. Создание контракта в начале или подход сверху вниз: В этом подходе мы сначала создаем контракт веб-сервиса, то есть файл WSDL, а затем создаем его реализацию.

В реализации службы предоставьте полный классифицированный путь к классу реализации PersonServiceImpl. Убедитесь, что вы переместили ползунок в службу и тип клиента на левую сторону, чтобы он мог создать клиентскую программу, а также интерфейс для тестирования нашей веб-службы. Проверьте конфигурации в реализации веб-службы, вы должны предоставить правильные детали для времени выполнения сервера, времени выполнения веб-службы и проекта службы. Обычно они автоматически заполняются, и вам не нужно вносить здесь изменения. Для конфигураций клиента вы можете указать имя клиентского проекта, как вам удобно. Я оставил его по умолчанию как SOAPExampleClient. Если вы нажмете на ссылку для времени выполнения веб-службы, вы получите различные варианты, как показано на изображении ниже. Однако я оставил его как значение по умолчанию. Нажмите кнопку “Далее”, и затем вы сможете выбрать методы, которые вы хотите выставить веб-службой. Вы также сможете выбрать стиль веб-службы как документ или буквально. Вы можете изменить имя документа WSDL, но лучше иметь его с именем класса реализации, чтобы избежать путаницы позже. Нажмите кнопку “Далее”, и у вас появится страница запуска сервера, нажмите кнопку “Запустить сервер”, а затем кнопка “Далее” станет активной. Нажмите кнопку “Далее”, и у вас появится страница для запуска “Исследователя веб-служб”. Нажмите кнопку “Запуск”, и откроется новое окно в браузере, где вы сможете протестировать свою веб-службу перед переходом к части клиентского приложения. Это выглядит как на изображении ниже для нашего проекта. Здесь мы можем провести некоторые тесты для проверки работоспособности, но для нашего простого приложения я готов перейти к созданию клиентского приложения. Нажмите кнопку “Далее” во всплывающем окне веб-служб Eclipse, и у вас появится страница для выбора исходной папки для клиентского приложения. Нажмите кнопку “Далее”, и у вас появятся различные варианты для выбора в качестве средства тестирования. Я собираюсь использовать JAX-RPC JSPs, чтобы клиентское приложение создало страницу JSP, которую мы сможем использовать. Обратите внимание на методы getEndpoint() и setEndpoint(String), добавленные, чтобы мы могли получить URL конечной точки веб-службы и установить его в другой URL в случае перемещения сервера. Нажмите кнопку “Готово”, и Eclipse создаст клиентский проект в вашем рабочем пространстве, также запустит тестовую страницу JSP клиента, как показано ниже. Вы можете скопировать URL и открыть его в любом браузере по вашему выбору. Давайте протестируем некоторые из предоставленных нами служб и посмотрим результат.

Тестирование веб-сервисов SOAP Eclipse

  • addPerson

  • getPerson

  • 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