Création d'un service Web SOAP avec Spring

1. Vue d'ensemble

Dans ce didacticiel, nous verrons comment créer un service Web basé sur SOAP avec les services Web Spring Boot Starter.

2. Services Web SOAP

Un service Web est, en bref, un service de machine à machine indépendant de la plate-forme qui permet la communication sur un réseau.

SOAP est un protocole de messagerie. Les messages (demandes et réponses) sont des documents XML sur HTTP . Le contrat XML est défini par le WSDL (Web Services Description Language). Il fournit un ensemble de règles pour définir les messages, les liaisons, les opérations et l'emplacement du service.

Le XML utilisé dans SOAP peut devenir extrêmement complexe. Pour cette raison, il est préférable d'utiliser SOAP avec un framework comme JAX-WS ou Spring, comme nous le verrons dans ce tutoriel.

3. Style de développement axé sur le contrat

Il existe deux approches possibles lors de la création d'un service Web: Contract-Last et Contract-First. Lorsque nous utilisons une approche contract-last, nous commençons avec le code Java, et nous générons le contrat de service Web (WSDL) à partir des classes. Lors de l'utilisation du contrat d'abord, nous commençons par le contrat WSDL, à partir duquel nous générons les classes Java.

Spring-WS prend uniquement en charge le style de développement contract-first.

4. Configuration du projet Spring Boot

Nous allons créer un projet Spring Boot dans lequel nous définirons notre serveur SOAP WS.

4.1. Dépendances de Maven

Commençons par ajouter le spring-boot-starter-parent à notre projet:

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

Ensuite, ajoutons les dépendances spring-boot-starter-web-services et wsdl4j :

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

4.2. Le fichier XSD

L'approche contract-first nous oblige à créer d'abord le domaine (méthodes et paramètres) pour notre service. Nous allons utiliser un fichier de schéma XML (XSD) que Spring-WS exportera automatiquement en tant que WSDL:

Dans ce fichier, nous voyons le format de la demande de service Web getCountryRequest . Nous le définissons pour accepter un paramètre de type string .

Ensuite, nous définissons le format de la réponse, qui contient un objet de type country .

Enfin, nous voyons l' objet devise , utilisé dans l' objet pays .

4.3. Générer les classes Java de domaine

Nous allons maintenant générer les classes Java à partir du fichier XSD défini dans la section précédente. Le jaxb2-maven-plugin le fera automatiquement pendant la construction. Le plugin utilise l'outil XJC comme moteur de génération de code. XJC compile le fichier de schéma XSD en classes Java entièrement annotées.

Ajoutons et configurons le plugin dans notre pom.xml:

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

On remarque ici deux configurations importantes:

  • $ {project.basedir} / src / main / resources - L'emplacement du fichier XSD
  • $ {project.basedir} / src / main / java - Où nous voulons que notre code Java soit généré

Pour générer les classes Java, nous pourrions simplement utiliser l'outil xjc de notre installation Java. Bien que dans notre projet Maven, les choses soient encore plus simples, car les classes seront automatiquement générées lors de la construction habituelle de Maven:

mvn compile

4.4. Ajouter le point de terminaison du service Web SOAP

La classe de point de terminaison du service Web SOAP gérera toutes les demandes entrantes pour le service. Il lancera le traitement et renverra la réponse.

Avant de définir cela, nous créons un référentiel Pays afin de fournir des données au service 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); } } 

Ensuite, configurons le point de terminaison:

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

Voici quelques détails à noter:

  • @Endpoint - enregistre la classe avec Spring WS en tant que point de terminaison de service Web
  • @PayloadRoot - définit la méthode du gestionnaire en fonction de l' espace de noms et des attributs localPart
  • @ResponsePayload - indique que cette méthode renvoie une valeur à mapper à la charge utile de la réponse
  • @RequestPayload - indique que cette méthode accepte un paramètre à mapper à partir de la demande entrante

4.5. Les beans de configuration du service Web SOAP

Créons maintenant une classe pour configurer le servlet du répartiteur de messages Spring pour recevoir la demande:

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

@EnableWs active les fonctionnalités du service Web SOAP dans cette application Spring Boot. La classe WebServiceConfig étend la classe de base WsConfigurerAdapter , qui configure le modèle de programmation Spring-WS basé sur les annotations.

Créons un MessageDispatcherServlet qui est utilisé pour gérer les requêtes SOAP:

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

Nous définissons l' objet ApplicationContext injecté du servlet afin que Spring-WS puisse trouver d'autres beans Spring.

Nous activons également la transformation de servlet d'emplacement WSDL. Cela transforme l'attribut location de soap: address dans le WSDL afin qu'il reflète l'URL de la demande entrante.

Enfin, créons un objet DefaultWsdl11Definition . Cela expose un WSDL 1.1 standard utilisant un XsdSchema. Le nom WSDL sera le même que le nom du 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 du projet SOAP

Une fois la configuration du projet terminée, nous sommes prêts à la tester.

5.1. Construire et exécuter le projet

Il serait possible de créer un fichier WAR et de le déployer sur un serveur d'applications externe. Nous utiliserons plutôt Spring Boot, qui est un moyen plus rapide et plus simple de faire fonctionner l'application.

Tout d'abord, nous ajoutons la classe suivante pour rendre l'application exécutable:

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

Notez que nous n'utilisons aucun fichier XML (comme web.xml) pour créer cette application. Tout est pur Java.

Nous sommes maintenant prêts à créer et exécuter l'application:

mvn spring-boot:run

Pour vérifier si l'application fonctionne correctement, nous pouvons ouvrir le WSDL via l'URL: //localhost:8080/ws/countries.wsdl

5.2. Tester une requête SOAP

Pour tester une requête, nous créons le fichier suivant et le nommons request.xml:

    Spain    

Pour envoyer la demande à notre serveur de test, nous pourrions utiliser des outils externes comme SoapUI ou l'extension Google Chrome Wizdler. Une autre façon est d'exécuter la commande suivante dans notre shell:

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

La réponse qui en résulte peut ne pas être facile à lire sans retrait ni saut de ligne.

Pour le voir formaté, nous pouvons le copier-coller dans notre IDE ou dans un autre outil. Si nous avons installé xmllib2, nous pouvons diriger la sortie de notre commande curl vers xmllint :

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

La réponse doit contenir des informations sur l'Espagne:

     Spain 46704314 Madrid EUR     

6. Conclusion

Dans cet article, nous avons appris à créer un service Web SOAP à l'aide de Spring Boot. Nous avons également appris à générer du code Java à partir d'un fichier XSD, et nous avons vu comment configurer les beans Spring nécessaires pour traiter les requêtes SOAP.

Le code source complet est disponible à l'adresse over sur GitHub.