Ejemplo de servicios web SOAP en Java usando Eclipse

Los servicios web SOAP en Java pueden desarrollarse de muchas maneras. Aprendimos sobre los Servicios web SOAP JAX-WS en nuestro último tutorial, hoy aprenderemos cómo podemos crear un servicio web SOAP y su programa cliente usando Eclipse. Aquí no utilizaremos JAX-WS, estaremos utilizando Apache Axis que está integrado en Eclipse y proporciona una manera rápida y fácil de transformar una aplicación en un servicio web Java y crear stubs de cliente con una página JSP de prueba para propósitos de prueba.

Servicios web SOAP en Java

Estoy utilizando Eclipse Mars Release (4.5.0) para este tutorial, pero creo que estos pasos también funcionarán con versiones más antiguas de Eclipse. Además, asegúrese de haber agregado Apache Tomcat o cualquier otro contenedor de servlets como servidor en Eclipse. Comencemos con nuestra implementación de Servicio web Eclipse ahora.

Ejemplo de servicio web SOAP

Comencemos con nuestro ejemplo de servicio web SOAP en Eclipse. En primer lugar, crearemos un simple Proyecto Web Dinámico en Eclipse que contendrá la lógica empresarial para nuestra aplicación. Haz clic en el botón Siguiente arriba y llegarás a la siguiente página para proporcionar el nombre de tu proyecto web y Runtime Objetivo. Ten en cuenta que estoy utilizando Apache Tomcat 8, pero también puedes usar cualquier otro contenedor de servlets estándar. Haz clic en Siguiente y se te pedirá que proporciones el “Contexto Raíz” y la ubicación del Directorio de Contenido. Puedes dejarlos como están por defecto. Haz clic en Finalizar y Eclipse creará el esqueleto del proyecto para ti. Ahora, comencemos con nuestra lógica empresarial. Para nuestro ejemplo, queremos publicar un servicio web que pueda ser utilizado para agregar/eliminar/obtener un objeto. Así que el primer paso es crear un bean de modelo.

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;
	}

}

Observa que arriba es un simple bean de Java, estamos implementando la interfaz Serializable porque lo transportaremos a través de la red. También hemos proporcionado la implementación del método toString que se usará cuando imprimamos este objeto en el lado del cliente. El siguiente paso es crear clases de servicio, así que tendremos una interfaz llamada PersonService y su clase de implementación simple 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();
}

A continuación se muestra la clase de servicio de implementación, estamos usando un Map para almacenar objetos Person como fuente de datos. En la programación del mundo real, nos gustaría guardar estos en tablas de base de datos.

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;
	}

}

Esto es todo para nuestra lógica empresarial, ya que usaremos esto en un servicio web, no tiene sentido crear páginas web aquí. Observa que no tenemos referencia a ningún tipo de clases de servicios web en el código anterior.

Servicios web SOAP en Java usando Eclipse

Una vez que nuestra lógica empresarial esté lista, el siguiente paso es utilizar Eclipse para crear una aplicación de servicio web a partir de esto. Cree un nuevo proyecto y seleccione el asistente de Servicio web. Haga clic en el botón Siguiente y obtendrá una página donde se deben proporcionar los detalles del servicio web y su cliente. Esta es la página más importante en la creación de un servicio web. Asegúrese de seleccionar “Tipo de servicio web” como “Servicio web de Java con bean de abajo hacia arriba” porque estamos implementando con un enfoque de abajo hacia arriba. Hay dos formas de crear un servicio web:

  1. Contrato último o enfoque de abajo hacia arriba: En este enfoque, primero creamos la implementación y luego generamos el archivo WSDL a partir de ella. Nuestra implementación se ajusta a esta categoría.
  2. Contrato primero o enfoque de arriba hacia abajo: En este enfoque, primero creamos el contrato del servicio web, es decir, el archivo WSDL, y luego creamos la implementación para ello.

En la implementación del servicio, proporcione la ruta completamente clasificada de la clase de implementación PersonServiceImpl. Asegúrese de mover el deslizador en el tipo de servicio y cliente hacia el lado izquierdo para que pueda generar el programa cliente y también la interfaz de usuario para probar nuestro servicio web. Verifique las configuraciones en la implementación del servicio web, debería proporcionar los detalles correctos para el tiempo de ejecución del servidor, el tiempo de ejecución del servicio web y el proyecto de servicio. Por lo general, se completan automáticamente y no es necesario realizar ningún cambio aquí. Para las configuraciones del cliente, puede proporcionar el nombre del proyecto del cliente como desee. Lo he dejado como predeterminado, SOAPExampleClient. Si hace clic en el enlace para el tiempo de ejecución del servicio web, obtendrá diferentes opciones como se muestra en la imagen a continuación. Sin embargo, lo he dejado como el predeterminado. Haga clic en el botón Siguiente y luego podrá elegir los métodos que desea exponer como servicio web. También podrá elegir el estilo del servicio web como documento o literal. Puede cambiar el nombre del documento WSDL, pero es bueno tenerlo con el nombre de la clase de implementación para evitar confusiones más adelante. Haga clic en el botón Siguiente y obtendrá la página de inicio del servidor, haga clic en el botón “Iniciar servidor” y luego se habilitará el botón siguiente. Haga clic en el botón Siguiente y obtendrá una página para iniciar el “Explorador de servicios web”. Haga clic en el botón de lanzamiento y se abrirá una nueva ventana en el navegador donde puede probar su servicio web antes de continuar con la parte de la aplicación cliente. Se parece a la imagen a continuación para nuestro proyecto. Podemos hacer algunas pruebas de cordura aquí, pero para nuestra aplicación simple, estoy listo para continuar con la creación de la aplicación cliente. Haga clic en el botón Siguiente en la ventana emergente de servicios web de Eclipse y obtendrá una página para la carpeta de origen de la aplicación cliente. Haga clic en el botón Siguiente y obtendrá diferentes opciones para elegir como instalación de prueba. Estoy procediendo con JSPs JAX-RPC para que la aplicación cliente genere una página JSP que podamos usar. Note los métodos getEndpoint() y setEndpoint(String) que se agregaron y que podemos usar para obtener la URL del punto final del servicio web y podemos configurarla a alguna otra URL en caso de que movamos nuestro servidor a algún otro punto final de URL. Haga clic en el botón Finalizar y Eclipse creará el proyecto cliente en su espacio de trabajo, también lanzará la página de prueba del cliente JSP como se muestra a continuación. Puede copiar la URL y abrir en cualquier navegador que desee. Probemos algunos de los servicios que hemos expuesto y veamos la salida.

Prueba de Servicio Web SOAP de Eclipse

  • addPerson

  • getPerson

  • getAllPersons Tenga en cuenta que los detalles de la Persona no se imprimen en la sección de resultados, esto se debe a que es código generado automáticamente y necesitamos refactorizarlo un poco para obtener la salida deseada. Abra Result.jsp en el proyecto del cliente y verá que está utilizando un switch case para generar la salida del resultado. Para el método getAllPersons(), era el caso 42 en mi caso. Tenga en cuenta que podría ser totalmente diferente en su caso. Simplemente cambié el código para el caso 42 como se muestra a continuación.

    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;
    

    Después de eso obtenemos la siguiente salida, tenga en cuenta que Eclipse está realizando un despliegue en caliente aquí, así que no tuve que volver a implementar mi aplicación.

Así que parece que nuestro servicio web y las aplicaciones cliente están funcionando bien, asegúrate de dedicar tiempo a examinar los stubs del lado del cliente generados por Eclipse para entender más.

WSDL y Configuraciones del Servicio Web SOAP

Finalmente, notarás que el archivo WSDL se genera en el proyecto del servicio web como se muestra a continuación. Código de 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>

Si lo abrirás en modo de diseño en Eclipse, se verá como la imagen a continuación. También puedes acceder al archivo WSDL del servicio web a través del navegador agregando ?wsdl al punto final del servicio web. También notarás que se modificó el archivo web.xml para usar Apache Axis como controlador frontal para el servicio web.

<?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>

La imagen a continuación muestra el proyecto de servicio web y cliente con todos los stubs generados automáticamente y las páginas JSP para probar el servicio web. Eso es todo para los servicios web SOAP en Java usando Eclipse, como puedes ver, toda la parte difícil fue hecha automáticamente por Eclipse y todo nuestro enfoque fue escribir la lógica empresarial para nuestro servicio web.

Source:
https://www.digitalocean.com/community/tutorials/soap-webservices-in-java-example-eclipse