Creazione di un servizio Web SOAP con Spring

1. Panoramica

In questo tutorial vedremo come creare un servizio web basato su SOAP con Spring Boot Starter Web Services.

2. Servizi Web SOAP

Un servizio Web è, in breve, un servizio indipendente dalla piattaforma machine-to-machine che consente la comunicazione su una rete.

SOAP è un protocollo di messaggistica. I messaggi (richieste e risposte) sono documenti XML su HTTP . Il contratto XML è definito dal WSDL (Web Services Description Language). Fornisce una serie di regole per definire i messaggi, le associazioni, le operazioni e la posizione del servizio.

L'XML utilizzato in SOAP può diventare estremamente complesso. Per questo motivo, è meglio utilizzare SOAP con un framework come JAX-WS o Spring, come vedremo in questo tutorial.

3. Stile di sviluppo del primo contratto

Ci sono due possibili approcci durante la creazione di un servizio Web: Contract-Last e Contract-First. Quando usiamo un approccio per ultimo contratto, iniziamo con il codice Java e generiamo il contratto di servizio web (WSDL) dalle classi. Quando si utilizza contract-first, iniziamo con il contratto WSDL, da cui generiamo le classi Java.

Spring-WS supporta solo lo stile di sviluppo primo contratto.

4. Configurazione del progetto Spring Boot

Creeremo un progetto Spring Boot in cui definiremo il nostro server SOAP WS.

4.1. Dipendenze di Maven

Cominciamo aggiungendo lo spring-boot-starter-genitore al nostro progetto:

 org.springframework.boot spring-boot-starter-parent 2.2.6.RELEASE  

Successivamente, aggiungiamo le dipendenze spring-boot-starter-web-services e wsdl4j :

 org.springframework.boot spring-boot-starter-web-services   wsdl4j wsdl4j  

4.2. Il file XSD

L'approccio basato sul contratto ci richiede di creare prima il dominio (metodi e parametri) per il nostro servizio. Utilizzeremo un file di schema XML (XSD) che Spring-WS esporterà automaticamente come WSDL:

In questo file, vediamo il formato della richiesta del servizio web getCountryRequest . Lo definiamo per accettare un parametro della stringa di tipo .

Successivamente, definiamo il formato della risposta, che contiene un oggetto del tipo country .

Infine, vediamo l' oggetto valuta , utilizzato all'interno dell'oggetto paese .

4.3. Genera le classi Java del dominio

Creeremo ora le classi Java dal file XSD definito nella sezione precedente. Il plugin jaxb2-maven lo farà automaticamente durante la fase di compilazione. Il plugin utilizza lo strumento XJC come motore di generazione del codice. XJC compila il file dello schema XSD in classi Java completamente annotate.

Aggiungiamo e configuriamo il plugin nel nostro pom.xml:

 org.codehaus.mojo jaxb2-maven-plugin 1.6   xjc  xjc     ${project.basedir}/src/main/resources/ ${project.basedir}/src/main/java false   

Qui notiamo due importanti configurazioni:

  • $ {project.basedir} / src / main / resources - La posizione del file XSD
  • $ {project.basedir} / src / main / java - Dove vogliamo che venga generato il nostro codice Java

Per generare le classi Java, potremmo semplicemente usare lo strumento xjc dalla nostra installazione Java. Anche se nel nostro progetto Maven le cose sono ancora più semplici, poiché le classi verranno generate automaticamente durante la normale build di Maven:

mvn compile

4.4. Aggiungi l'endpoint del servizio Web SOAP

La classe dell'endpoint del servizio Web SOAP gestirà tutte le richieste in arrivo per il servizio. Avvierà l'elaborazione e invierà la risposta.

Prima di definirlo, creiamo un repository Paese per fornire dati al servizio web.

@Component public class CountryRepository { private static final Map countries = new HashMap(); @PostConstruct public void initData() { // initialize countries map } public Country findCountry(String name) { return countries.get(name); } } 

Successivamente, configuriamo l'endpoint:

@Endpoint public class CountryEndpoint { private static final String NAMESPACE_URI = "//www.baeldung.com/springsoap/gen"; private CountryRepository countryRepository; @Autowired public CountryEndpoint(CountryRepository countryRepository) { this.countryRepository = countryRepository; } @PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCountryRequest") @ResponsePayload public GetCountryResponse getCountry(@RequestPayload GetCountryRequest request) { GetCountryResponse response = new GetCountryResponse(); response.setCountry(countryRepository.findCountry(request.getName())); return response; } } 

Ecco alcuni dettagli da notare:

  • @Endpoint : registra la classe con Spring WS come endpoint del servizio Web
  • @PayloadRoot : definisce il metodo del gestore in base allo spazio dei nomi e agli attributi localPart
  • @ResponsePayload : indica che questo metodo restituisce un valore da mappare al payload della risposta
  • @RequestPayload : indica che questo metodo accetta un parametro da mappare dalla richiesta in arrivo

4.5. I bean di configurazione del servizio Web SOAP

Creiamo ora una classe per configurare il servlet del dispatcher di messaggi Spring per ricevere la richiesta:

@EnableWs @Configuration public class WebServiceConfig extends WsConfigurerAdapter { // bean definitions }

@EnableWs abilita le funzionalità del servizio Web SOAP in questa applicazione Spring Boot. La classe WebServiceConfig estende la classe base WsConfigurerAdapter , che configura il modello di programmazione Spring-WS basato sull'annotazione.

Creiamo un MessageDispatcherServlet che viene utilizzato per la gestione delle richieste SOAP:

@Bean public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) { MessageDispatcherServlet servlet = new MessageDispatcherServlet(); servlet.setApplicationContext(applicationContext); servlet.setTransformWsdlLocations(true); return new ServletRegistrationBean(servlet, "/ws/*"); } 

Abbiamo impostato l' oggetto ApplicationContext inserito del servlet in modo che Spring-WS possa trovare altri bean Spring.

Abilitiamo anche la trasformazione servlet posizione WSDL. Questo trasforma l'attributo di posizione di soap: address nel WSDL in modo che rifletta l'URL della richiesta in arrivo.

Infine, creiamo un oggetto DefaultWsdl11Definition . Questo espone un WSDL 1.1 standard utilizzando un XsdSchema. Il nome WSDL sarà lo stesso del nome del bean.

@Bean(name = "countries") public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) { DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition(); wsdl11Definition.setPortTypeName("CountriesPort"); wsdl11Definition.setLocationUri("/ws"); wsdl11Definition.setTargetNamespace("//www.baeldung.com/springsoap/gen"); wsdl11Definition.setSchema(countriesSchema); return wsdl11Definition; } @Bean public XsdSchema countriesSchema() { return new SimpleXsdSchema(new ClassPathResource("countries.xsd")); } 

5. Test del progetto SOAP

Una volta completata la configurazione del progetto, siamo pronti per testarlo.

5.1. Compilare ed eseguire il progetto

It would be possible to create a WAR file and deploy it to an external application server. We'll instead use Spring Boot, which is a faster and easier way to get the application up and running.

First, we add the following class to make the application executable:

@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 

Notice that we're not using any XML files (like web.xml) to create this application. It's all pure Java.

Now we're ready to build and run the application:

mvn spring-boot:run

To check if the application is running properly, we can open the WSDL through the URL: //localhost:8080/ws/countries.wsdl

5.2. Test a SOAP Request

To test a request, we create the following file and name it request.xml:

    Spain    

To send the request to our test server, we could use external tools like SoapUI or the Google Chrome extension Wizdler. Another way is to run the following command in our shell:

curl --header "content-type: text/xml" -d @request.xml //localhost:8080/ws

La risposta risultante potrebbe non essere facile da leggere senza rientri o interruzioni di riga.

Per vederlo formattato, possiamo copiarlo e incollarlo nel nostro IDE o in un altro strumento. Se abbiamo installato xmllib2, possiamo reindirizzare l'output del nostro comando curl a xmllint :

curl [command-line-options] | xmllint --format -

La risposta dovrebbe contenere informazioni sulla Spagna:

     Spain 46704314 Madrid EUR     

6. Conclusione

In questo articolo abbiamo imparato come creare un servizio web SOAP utilizzando Spring Boot. Abbiamo anche imparato a generare codice Java da un file XSD e abbiamo visto come configurare i bean Spring necessari per elaborare le richieste SOAP.

Il codice sorgente completo è disponibile su GitHub.