Web Service SOAP in Java Esempio utilizzando Eclipse

I servizi Web SOAP in Java possono essere sviluppati in molti modi. Abbiamo appreso di JAX-WS SOAP Web Services nel nostro ultimo tutorial, oggi impareremo come creare un servizio Web SOAP e il suo programma client utilizzando Eclipse. Qui non useremo JAX-WS, utilizzeremo Apache Axis integrato in Eclipse che fornisce un modo rapido e facile per trasformare un’applicazione in un servizio Web Java e creare stub client con una pagina JSP di test per scopi di test.

Servizi Web SOAP in Java

Sto utilizzando Eclipse Mars Release (4.5.0) per questo tutorial, ma penso che questi passaggi funzioneranno anche con le versioni più vecchie di Eclipse. Assicurati di aver aggiunto Apache Tomcat o qualsiasi altro contenitore servlet come server in Eclipse. Iniziamo ora con la nostra implementazione del Servizio Web Eclipse.

Esempio di Servizio Web SOAP

Iniziamo con il nostro esempio di servizio web SOAP in Eclipse. Prima di tutto creeremo un semplice Progetto Web Dinamico in Eclipse che conterrà la logica di business per la nostra applicazione. Fai clic sul pulsante Avanti sopra e otterrai la pagina successiva per fornire il nome del tuo progetto web e Target Runtime. Nota che sto usando Apache Tomcat 8, puoi utilizzare anche un altro contenitore servlet standard. Fai clic su Avanti e ti verrà chiesto di fornire “Context Root” e la posizione della directory dei contenuti. Puoi lasciarli come impostazione predefinita. Fai clic su Fine e Eclipse creerà lo scheletro del progetto per te. Iniziamo con la nostra logica di business. Quindi, per il nostro esempio, vorremmo pubblicare un servizio web che possa essere utilizzato per aggiungere/eliminare/ottenere un oggetto. Il primo passo è creare un bean di modello.

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

}

Si noti che sopra c’è un semplice Java bean, stiamo implementando l’interfaccia Serializable perché lo trasporteremo sulla rete. Abbiamo anche fornito un’implementazione del metodo toString che verrà utilizzato quando stampiamo questo oggetto sul lato client. Il passo successivo è creare le classi di servizio, quindi avremo un’interfaccia chiamata PersonService e la sua semplice classe di implementazione chiamata 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();
}

Di seguito è riportata l’implementazione della classe di servizio, stiamo utilizzando una mappa per memorizzare gli oggetti Person come origine dei dati. Nella programmazione del mondo reale, vorremmo salvarli nelle tabelle del database.

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

}

Questo è tutto per la nostra logica di business, poiché useremo queste in un servizio web, non ha senso creare pagine web qui. Si noti che non abbiamo alcun riferimento a nessun tipo di classe di servizi web nel codice sopra.

Servizi Web SOAP in Java utilizzando Eclipse

Una volta pronta la nostra logica aziendale, il passo successivo è utilizzare Eclipse per creare un’applicazione di servizio web da questa. Crea un nuovo progetto e seleziona la wizard di servizio web. Fai clic sul pulsante Avanti e otterrai una pagina in cui devono essere forniti i dettagli del servizio web e del suo client. Questa è la pagina più importante nella creazione di un servizio web. Assicurati di selezionare “Tipo di servizio web” come “Servizio web Java bean bottom up” perché stiamo implementando l’approccio bottom up. Ci sono due modi per creare un servizio web:

  1. Contratto dopo o approccio bottom up: In questo approccio prima creiamo l’implementazione e quindi generiamo il file WSDL da esso. La nostra implementazione rientra in questa categoria.
  2. Contratto prima o approccio top down: In questo approccio, prima creiamo il contratto del servizio web, ovvero il file WSDL, e quindi creiamo l’implementazione per esso.

Nell’implementazione del servizio, fornire il percorso completamente qualificato della classe di implementazione PersonServiceImpl. Assicurarsi di spostare il cursore nel tipo di servizio e di client verso sinistra in modo da poter generare il programma del client e anche l’interfaccia utente per testare il nostro servizio web. Verificare le configurazioni nell’implementazione del servizio web, è necessario fornire i dettagli corretti per il runtime del server, il runtime del servizio web e il progetto del servizio. Di solito vengono autopopolate e non è necessario apportare alcuna modifica qui. Per le configurazioni del client, è possibile fornire il nome del progetto del client come si preferisce. Io l’ho lasciato come predefinito SOAPExampleClient. Se si fa clic sul collegamento per il runtime del servizio web, si otterranno diverse opzioni come mostrato nell’immagine sottostante. Tuttavia, l’ho lasciato come predefinito. Fare clic sul pulsante Avanti e quindi sarà possibile scegliere i metodi che si desidera esporre come servizio web. Sarà anche possibile scegliere lo stile del servizio web come documento o letterale. È possibile modificare il nome del documento WSDL, ma è buono averlo con il nome della classe di implementazione per evitare confusione in seguito. Fare clic sul pulsante Avanti e si otterrà la pagina di avvio del server, fare clic sul pulsante “Avvia server” e quindi il pulsante successivo sarà abilitato. Fare clic sul pulsante Avanti e si otterrà una pagina per avviare l'”Esploratore dei servizi Web”. Fare clic sul pulsante Avvia e si aprirà una nuova finestra nel browser in cui è possibile testare il servizio web prima di procedere con la parte dell’applicazione client. Appare come nell’immagine sottostante per il nostro progetto. Possiamo fare alcuni test preliminari qui, ma per la nostra semplice applicazione sono pronto a procedere con la creazione dell’applicazione client. Fare clic sul pulsante Avanti nella finestra popup dei servizi web di Eclipse e si otterrà una pagina per la cartella di origine dell’applicazione client. Fare clic sul pulsante Avanti e si otterranno diverse opzioni da scegliere come strumento di test. Sto procedendo con JSP JAX-RPC in modo che l’applicazione client generi una pagina JSP che possiamo utilizzare. Notare i metodi getEndpoint() e setEndpoint(String) aggiunti che possiamo utilizzare per ottenere l’URL dell’endpoint del servizio web e possiamo impostarlo su un altro URL nel caso in cui spostiamo il nostro server su un altro endpoint URL. Fare clic sul pulsante Fine e Eclipse creerà il progetto client nel proprio workspace, avvierà anche la pagina di test del client come mostrato di seguito. È possibile copiare l’URL e aprirlo in qualsiasi browser si preferisca. Proviamo alcuni dei servizi che abbiamo esposto e vediamo l’output.

Test del servizio Web SOAP di Eclipse

  • addPerson

  • getPerson

  • getAllPersons Si noti che i dettagli della persona non vengono stampati nella sezione dei risultati, questo perché è un codice generato automaticamente e dobbiamo modificarlo leggermente per ottenere l’output desiderato. Apri Result.jsp nel progetto client e vedrai che utilizza uno switch case per generare l’output dei risultati. Per il metodo getAllPersons(), era il case 42 nel mio caso. Nota che potrebbe essere completamente diverso nel tuo caso. Ho appena modificato il codice per il case 42 come mostrato di seguito.

    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;
    

    Dopo di ciò otteniamo l’output seguente, nota che Eclipse sta facendo un hot deployment qui, quindi non ho dovuto ridistribuire la mia applicazione.

Sembra che il nostro servizio web e le applicazioni client funzionino correttamente, assicurati di dedicare del tempo a esaminare gli stub lato client generati da Eclipse per capire meglio.

WSDL del servizio web SOAP e configurazioni

Infine, noterai che il file WSDL viene generato nel progetto del servizio web come mostrato di seguito. Codice 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>

Se lo apri in modalità di progettazione in Eclipse, apparirà come nell’immagine sottostante. Puoi anche accedere al file WSDL del servizio web tramite il browser aggiungendo ?wsdl all’endpoint del servizio web. Noterai anche che il file web.xml è stato modificato per utilizzare Apache Axis come controller front-end per il servizio 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>

Nell’immagine sottostante viene mostrato il progetto del servizio web e del client con tutti gli stub e le pagine JSP generate automaticamente per testare il servizio web. Questo è tutto per gli esempi di servizi web con SOAP in Java utilizzando Eclipse, come puoi vedere, la parte difficile è stata fatta automaticamente da Eclipse e tutto il nostro focus era sulla scrittura della logica di business per il nostro servizio web.

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