Erstellen eines SOAP-Webdienstes mit Spring

1. Übersicht

In diesem Tutorial erfahren Sie, wie Sie mit Spring Boot Starter Web Services einen SOAP-basierten Webdienst erstellen .

2. SOAP-Webdienste

Ein Webdienst ist kurz gesagt ein plattformunabhängiger Dienst von Maschine zu Maschine, der die Kommunikation über ein Netzwerk ermöglicht.

SOAP ist ein Messaging-Protokoll. Nachrichten (Anfragen und Antworten) sind XML-Dokumente über HTTP . Der XML-Vertrag wird von der WSDL (Web Services Description Language) definiert. Es enthält eine Reihe von Regeln zum Definieren der Nachrichten, Bindungen, Vorgänge und des Speicherorts des Dienstes.

Das in SOAP verwendete XML kann äußerst komplex werden. Aus diesem Grund ist es am besten, SOAP mit einem Framework wie JAX-WS oder Spring zu verwenden, wie wir in diesem Tutorial sehen werden.

3. Vertrags-erster Entwicklungsstil

Beim Erstellen eines Webdienstes gibt es zwei mögliche Ansätze: Contract-Last und Contract-First. Wenn wir einen Vertrag-Last-Ansatz verwenden, beginnen wir mit dem Java-Code und generieren den Webdienstvertrag (WSDL) aus den Klassen. Bei Verwendung von contract-first beginnen wir mit dem WSDL-Vertrag, aus dem wir die Java-Klassen generieren.

Spring-WS unterstützt nur den Entwicklungsstil "Contract First".

4. Einrichten des Spring Boot-Projekts

Wir werden ein Spring Boot-Projekt erstellen, in dem wir unseren SOAP WS-Server definieren.

4.1. Maven-Abhängigkeiten

Beginnen wir mit dem Hinzufügen des Spring-Boot-Starter-Parent zu unserem Projekt:

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

Als nächstes fügen wir die Abhängigkeiten Spring-Boot-Starter-Web-Services und wsdl4j hinzu :

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

4.2. Die XSD-Datei

Der Contract-First-Ansatz erfordert, dass wir zuerst die Domäne (Methoden und Parameter) für unseren Service erstellen. Wir werden eine XML-Schemadatei (XSD) verwenden, die Spring-WS automatisch als WSDL exportiert:

In dieser Datei sehen wir das Format der getCountryRequest- Webdienstanforderung . Wir definieren es so, dass ein Parameter des Typs string akzeptiert wird .

Als nächstes definieren wir das Format der Antwort, die ein Objekt vom Typ Land enthält .

Endlich sehen wir das Währungs Objekt innerhalb des verwendeten Land Objekt.

4.3. Generieren Sie die Domänen-Java-Klassen

Wir werden jetzt die Java-Klassen aus der im vorherigen Abschnitt definierten XSD-Datei generieren. Das jaxb2-maven-Plugin erledigt dies automatisch während der Erstellungszeit. Das Plugin verwendet das XJC-Tool als Code-Generierungs-Engine. XJC kompiliert die XSD-Schemadatei in vollständig kommentierte Java-Klassen.

Fügen wir das Plugin in unserer pom.xml hinzu und konfigurieren es:

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

Hier sehen wir zwei wichtige Konfigurationen:

  • $ {project.basedir} / src / main / resources - Der Speicherort der XSD-Datei
  • $ {project.basedir} / src / main / java - Wo soll unser Java-Code generiert werden?

Um die Java-Klassen zu generieren, können wir einfach das xjc-Tool aus unserer Java-Installation verwenden. In unserem Maven-Projekt sind die Dinge jedoch noch einfacher, da die Klassen während des üblichen Maven-Builds automatisch generiert werden :

mvn compile

4.4. Fügen Sie den SOAP-Webdienst-Endpunkt hinzu

Die SOAP-Webdienst-Endpunktklasse verarbeitet alle eingehenden Anforderungen für den Dienst. Es wird die Verarbeitung initiieren und die Antwort zurücksenden.

Bevor wir dies definieren, erstellen wir ein Länder- Repository, um dem Webdienst Daten bereitzustellen.

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

Als nächstes konfigurieren wir den Endpunkt:

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

Hier sind einige Details zu beachten:

  • @Endpoint - registriert die Klasse bei Spring WS als Webdienst-Endpunkt
  • @PayloadRoot - Definiert die Handler-Methode gemäß den Attributen Namespace und localPart
  • @ResponsePayload - Gibt an, dass diese Methode einen Wert zurückgibt, der der Antwortnutzlast zugeordnet werden soll
  • @RequestPayload - Gibt an, dass diese Methode einen Parameter akzeptiert, der aus der eingehenden Anforderung zugeordnet werden soll

4.5. Die SOAP-Webdienst-Konfigurationsbeans

Erstellen wir nun eine Klasse zum Konfigurieren des Spring Message Dispatcher-Servlets zum Empfangen der Anforderung:

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

@EnableWs aktiviert SOAP-Webdienstfunktionen in dieser Spring Boot-Anwendung. Die WebServiceConfig- Klasse erweitert die WsConfigurerAdapter- Basisklasse, die das annotationsgesteuerte Spring-WS-Programmiermodell konfiguriert.

Erstellen wir ein MessageDispatcherServlet, das zur Verarbeitung von SOAP-Anforderungen verwendet wird:

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

Wir setzen das injizierte ApplicationContext- Objekt des Servlets so, dass Spring-WS andere Spring-Beans finden kann.

Wir aktivieren auch die WSDL-Standort-Servlet-Transformation. Dadurch wird das Standortattribut von soap: address in der WSDL so transformiert , dass es die URL der eingehenden Anforderung widerspiegelt.

Zuletzt erstellen wir ein DefaultWsdl11Definition- Objekt. Dadurch wird eine Standard-WSDL 1.1 mit einem XsdSchema verfügbar gemacht. Der WSDL-Name entspricht dem Bean-Namen.

@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. Testen des SOAP-Projekts

Sobald die Projektkonfiguration abgeschlossen ist, können wir sie testen.

5.1. Erstellen Sie das Projekt und führen Sie es aus

Es wäre möglich, eine WAR-Datei zu erstellen und auf einem externen Anwendungsserver bereitzustellen. Wir werden stattdessen Spring Boot verwenden, eine schnellere und einfachere Möglichkeit, die Anwendung zum Laufen zu bringen.

Zuerst fügen wir die folgende Klasse hinzu, um die Anwendung ausführbar zu machen:

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

Beachten Sie, dass wir keine XML-Dateien (wie web.xml) verwenden, um diese Anwendung zu erstellen. Es ist alles reines Java.

Jetzt können wir die Anwendung erstellen und ausführen:

mvn spring-boot:run

Um zu überprüfen, ob die Anwendung ordnungsgemäß ausgeführt wird, können Sie die WSDL über die URL //localhost:8080/ws/countries.wsdl öffnen

5.2. Testen Sie eine SOAP-Anfrage

Um eine Anfrage zu testen, erstellen wir die folgende Datei und nennen sie request.xml:

    Spain    

Um die Anfrage an unseren Testserver zu senden, können wir externe Tools wie SoapUI oder die Google Chrome-Erweiterung Wizdler verwenden. Eine andere Möglichkeit besteht darin, den folgenden Befehl in unserer Shell auszuführen:

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

Die resultierende Antwort ist ohne Einrückung oder Zeilenumbrüche möglicherweise nicht leicht zu lesen.

Um es formatiert zu sehen, können wir es kopieren und in unsere IDE oder ein anderes Tool einfügen. Wenn wir xmllib2 installiert haben, wir können die Ausgabe unseres curl Befehl xmllint :

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

Die Antwort sollte Informationen über Spanien enthalten:

     Spain 46704314 Madrid EUR     

6. Fazit

In diesem Artikel haben wir gelernt, wie Sie mit Spring Boot einen SOAP-Webdienst erstellen. Wir haben auch gelernt, wie Java-Code aus einer XSD-Datei generiert wird, und wir haben gesehen, wie die Spring Beans konfiguriert werden, die zur Verarbeitung der SOAP-Anforderungen erforderlich sind.

Der vollständige Quellcode ist auf GitHub verfügbar.