Java >> Java Tutorial >  >> Tag >> Spring

Produzieren und Konsumieren von SOAP-Webdiensten mit Spring Boot – Teil V

In diesem Beitrag beschreiben wir, wie Sie einen SOAP-Webservice aus unserer vorhandenen Spring Boot-REST-API erstellen. In den letzten Beiträgen haben wir Folgendes behandelt

  1. Spring Boot REST CRUD API – Teil I
  2. Swagger-Dokumentation für die Spring Boot-REST-API – Teil II
  3. Fehlerbehandlung und -protokollierung in der Spring Boot-REST-API – Teil III
  4. Nutzung des RESTful-Webdienstes – Teil IV

Dieser SOAP-Webservice stellt uns Benutzerdaten aus der Datenbank zur Verfügung, die wir über Spring-data in Spring REST API verbunden haben.

1. Anforderungen

  1. Eclipse Mars2
  2. Maven 3.1 und höher
  3. Spring 1.4 und höher
  4. Java 7
  5. Tomcat 8

2. SOAP-Webdienst

Wir werden unsere vorhandene Spring Boot-REST-API verwenden, um eine Anwendung zu erstellen, die als SOAP-Webdienst fungiert, um Benutzerdaten bereitzustellen. Für eine bestimmte Benutzer-ID gibt der Webdienst Benutzerdaten zurück.

Lassen Sie uns eine Schemadatei in src/main/resources erstellen Verzeichnis und Maven erstellt Java-Klassen basierend auf dieser Schemadatei.


<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="https://betterjavacode.com/benefits/soap" targetNamespace="https://betterjavacode.com/benefits/soap" elementFormDefault="qualified">
	<xs:element name="getUserRequest">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="id" type="xs:int"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:element name="getUserResponse">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="user" type="tns:user"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:complexType name="user">
		<xs:sequence>
			<xs:element name="id" type="xs:int"/>
			<xs:element name="firstname" type="xs:string"/>
			<xs:element name="middlename" type="xs:string"/>
			<xs:element name="lastname" type="xs:string"/>
			<xs:element name="username" type="xs:string"/>
			<xs:element name="createdate" type="xs:date"/>
			<xs:element name="jobtitle" type="xs:string"/>
			<xs:element name="email" type="xs:string"/>
		</xs:sequence>
	</xs:complexType>
</xs:schema>

3. Aktualisieren Sie die Maven-Abhängigkeiten

Um jetzt Klassen aus dem Schema zu generieren, müssen wir sicherstellen, dass wir alle richtigen Abhängigkeiten in unserem pom.xml haben . Wir werden auch eine Spring-Boot-Dienstabhängigkeit hinzufügen, um einen SOAP-Webdienst zu erstellen.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.betterjavacode</groupId>
 <artifactId>Benefits</artifactId>
 <packaging>war</packaging>
 <version>0.0.1-SNAPSHOT</version>
 <name>Benefits Maven Webapp</name>
 <url>http://maven.apache.org</url>
 <parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>1.4.2.RELEASE</version>
 </parent>
 <dependencies>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-jpa</artifactId>
 </dependency>
 <dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 <scope>runtime</scope>
 </dependency>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-jdbc</artifactId>
 </dependency>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-test</artifactId>
 </dependency>
 <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-api</artifactId>
 </dependency>
 <dependency>
 <groupId>io.swagger</groupId>
 <artifactId>swagger-jersey2-jaxrs</artifactId>
 <version>1.5.12</version>
 </dependency>
 <dependency>
 <groupId>io.springfox</groupId>
 <artifactId>springfox-swagger2</artifactId>
 <version>2.6.1</version>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>io.springfox</groupId>
 <artifactId>springfox-swagger-ui</artifactId>
 <version>2.6.1</version>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>org.apache.logging.log4j</groupId>
 <artifactId>log4j-api</artifactId>
 </dependency>
 <dependency>
 <groupId>org.apache.logging.log4j</groupId>
 <artifactId>log4j-core</artifactId>
 </dependency>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web-services</artifactId>
 </dependency>
 <dependency>
 <groupId>wsdl4j</groupId>
 <artifactId>wsdl4j</artifactId>
 </dependency>
 <dependency>
 <groupId>javax.xml.bind</groupId>
 <artifactId>jaxb-api</artifactId>
 <version>2.1</version>
 </dependency>
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <scope>test</scope>
 </dependency>
 </dependencies>
 <build>
 <plugins>
 <plugin>
 <artifactId>maven-compiler-plugin</artifactId>
 <version>3.3</version>
 <configuration>
 <source>1.8</source>
 <target>1.8</target>
 </configuration>
 </plugin>
 <plugin>
 <artifactId>maven-war-plugin</artifactId>
 <version>2.6</version>
 <configuration>
 <warSourceDirectory>WebContent</warSourceDirectory>
 <failOnMissingWebXml>false</failOnMissingWebXml>
 </configuration>
 </plugin>
 <plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>jaxb2-maven-plugin</artifactId>
 <version>1.6</version>
 <executions>
 <execution>
 <id>xjc</id>
 <goals>
 <goal>xjc</goal>
 </goals>
 </execution>
 </executions>
 <configuration>
 <schemaDirectory>${project.basedir}/src/main/resources/</schemaDirectory>
 <outputDirectory>${project.basedir}/src/main/java</outputDirectory>
 <clearOutputDir>false</clearOutputDir>
 <schemaLanguage>WSDL</schemaLanguage>
 <generatePackage>com.betterjavacode.benefits.soap</generatePackage>
 <forceRegenerate>true</forceRegenerate>
 <scehmas>
 <schema>
 <url>http://localhost:8080/benefits/endpoints/users.wsdl</url>
 </schema>
 </scehmas>
 </configuration>
 </plugin>
 </plugins>
 <finalName>Benefits</finalName>
 </build>
 </project>

Wenn wir das Projekt jetzt mit Maven Build ausführen, generiert das Plugin jaxb2-maven-plugin Klassen unter com.betterjavacode.benefits.soap Verzeichnis. Es wird auch unsere WSDL-SOAP-URL für Benutzer aktivieren. Dadurch werden folgende Java-Objekte generiert

  • GetUserRequest
  • GetUserResponse
  • ObjectFactory
  • package-info
  • User

4. Dienst definieren

Als Nächstes definieren wir eine Schnittstelle für unseren Dienst. Dies sieht wie folgt aus


package com.betterjavacode.benefits.services;

public interface UserAccountService
{
    public com.betterjavacode.benefits.soap.user.getUserDetails(int id);
}

Die Implementierung dieses Dienstes wird die Entitätsklasse User auf die generierte Klasse für den Soap-Service User abbilden. Unter Verwendung der ID als Schlüssel zum Abrufen von Benutzerdaten aus dem Repository werden wir dem Soap-Service-Benutzer zugeordnet. Für Post-Zwecke zeigen wir die Implementierung dieser Schnittstelle nicht.

5. Dienstendpunkt erstellen

Was ist ein Dienstendpunkt? Wenn eine SOAP-Anforderung für eine definierte URL vom Spring-Servlet verarbeitet wird, leitet das Spring-Servlet diese Anforderung an den Dienstendpunkt weiter. Der Dienstendpunkt verarbeitet dann diese Anfrage, um eine Antwort zu erstellen. Unsere spring-boot-starter-web-services Abhängigkeit bringt alle notwendigen Klassen für Annotationszwecke.


package com.betterjavacode.benefits.services.endpoints; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.ws.server.endpoint.annotation.Endpoint; 
import org.springframework.ws.server.endpoint.annotation.PayloadRoot; 
import org.springframework.ws.server.endpoint.annotation.RequestPayload; 
import org.springframework.ws.server.endpoint.annotation.ResponsePayload; 
import com.betterjavacode.benefits.services.UserAccountService; 
import com.betterjavacode.benefits.soap.GetUserRequest; 
import com.betterjavacode.benefits.soap.GetUserResponse; 
import com.betterjavacode.benefits.soap.User; 

@Endpoint 
public class UserAccountServiceEndpoint 
{ 
  // private static final String TARGET_NAMESPACE ="http://com/betterjavacode/benefits/webservices/useraccountservice";  
  private static final String TARGET_NAMESPACE =   "https://betterjavacode.com/benefits/soap"; 
  @Autowired private UserAccountService userAccountService; 
  @PayloadRoot(localPart = "getUserRequest", namespace = TARGET_NAMESPACE) 

  public @ResponsePayload GetUserResponse getUserRequest(@RequestPayload    GetUserRequest request) 
  {  
     GetUserResponse response = new GetUserResponse(); 
     User user = userAccountService.getUserDetails(request.getId()); 
     response.setUser(user); 
     return response; 
   } 
}

@Endpoint Annotation ermöglicht es, die Klasse als Dienstendpunkt zu definieren und in @Component aufzunehmen Anmerkung zum Scannen. Stellen Sie sicher, dass der in dieser Klasse definierte Namespace mit der XSD-Schemadefinition übereinstimmt. Andernfalls kann ein Fehler für „Kein Endpunkt definiert für auftreten “.

6. Konfiguration

Als Nächstes konfigurieren wir unsere Konfigurationsklasse, um den WSDL-Endpunkt zu generieren. Diese Konfigurationsklasse wird mit @EnableWs kommentiert, um die Webdienstkonfiguration bereitzustellen.


package com.betterjavacode.benefits;

import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
import org.springframework.xml.xsd.SimpleXsdSchema;
import org.springframework.xml.xsd.XsdSchema;

@Configuration
@EnableWs
@ComponentScan("com.betterjavacode")
public class AppConfig extends WsConfigurerAdapter
{

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

	@Bean(name="users")
	public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema usersSchema)
	{
		DefaultWsdl11Definition wsdl11definition = new DefaultWsdl11Definition();
		wsdl11definition.setPortTypeName("UserAccountService");
		wsdl11definition.setLocationUri("/endpoints");
		wsdl11definition.setTargetNamespace("http://com/betterjavacode/benefits/webservices/useraccountservice");
		wsdl11definition.setSchema(usersSchema);
		return wsdl11definition;
	}

	@Bean
	public XsdSchema usersSchema()
	{
		return new SimpleXsdSchema(new ClassPathResource("employees.xsd"));
	}
}

Einige wichtige Punkte zu dieser Konfigurationsklasse sind

  • MessageDispatcherServlet ist ein erforderliches Servlet zum Versenden von Webdienstnachrichten. Wir setzen dieses Servlet mit einer Bean, um die URL zu verarbeiten, von der die Anfrage kommt.
  • DefaultWsdl11Definition erstellt SOAP für das angegebene XSD-Schema
  • XsdSchema bietet eine Abstraktion für das XSD-Schema unserer Benutzer

7. Ausführen des SOAP-Webservice

Bauen Sie jetzt unser Projekt mit maven. Führen Sie die Spring-Boot-Anwendung über Eclipse aus, um den eingebetteten Tomcat-Server zu starten. Sobald der Tomcat-Server startet, wenn wir auf die URL http://localhost:8080/benefits/endpoints/users.wsdl zugreifen

Die Ausgabe im Browser erfolgt wie folgt

Hier haben wir gezeigt, wie man einen einfachen SOAP-Webdienst erstellt, den wir mit dem Spring Boot REST API-Dienst kombiniert haben. Wir können diesen SOAP-Webservice auch mit der Soap-Benutzeroberfläche testen, wie im folgenden Screenshot gezeigt

8. Nutzung des SOAP-Webdienstes

In den vorherigen Schritten haben wir gezeigt, wie ein SOAP-Webdienst erstellt wird. Jetzt zeigen wir, wie dieser SOAP-Webdienst programmgesteuert genutzt wird.

8.1 Erstellen Sie eine Client-Klasse

Unter Paket com.betterjavacode.benefits.views , definieren Sie eine Klasse UserClient wodurch ein WebServiceGatewaySupport erweitert wird Klasse. WebServiceGatewaySupport -Klasse stellt Webservice-Methoden bereit.


package com.betterjavacode.benefits.views; 

import org.springframework.ws.client.core.support.WebServiceGatewaySupport; 
import org.springframework.ws.soap.client.core.SoapActionCallback; 
import com.betterjavacode.benefits.soap.GetUserRequest; 
import com.betterjavacode.benefits.soap.GetUserResponse; 

public class UserClient extends WebServiceGatewaySupport 
{

   public GetUserResponse getUserById(int userid) 
   { 
      GetUserRequest userrequest = new GetUserRequest(); userrequest.setId(userid); 
      GetUserResponse response = (GetUserResponse) getWebServiceTemplate().marshalSendAndReceive(userrequest, new SoapActionCallback("http://localhost:8080/benefits/endpoints/getUserResponse"));  
      return response;  
    }  
}

8.2 Den Client für die Spring Bean-Unterstützung konfigurieren

Wir werden Jaxb2Marshaller so konfigurieren, dass JAXB unterstützt wird, um den Kontextpfad festzulegen. Dies wird uns helfen, unsere XML-Anfrage und -Antwort zu marshall und unmarshall.


package com.betterjavacode.benefits.views; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.oxm.jaxb.Jaxb2Marshaller; 

@Configuration 
public class ClientAppConfig 
{ 

   @Bean 
   public Jaxb2Marshaller marshaller() 
   {  
       Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); 
       marshaller.setContextPath("com.betterjavacode.benefits.soap"); 
       return marshaller;  
    } 
    
    @Bean 
    public UserClient userClient(Jaxb2Marshaller marshaller)  
    {  
        // WSDL URL - http://localhost:8080/benefits/endpoints/users.wsdl 
        UserClient uc = new UserClient(); 
        uc.setDefaultUri("http://localhost:8080/benefits/endpoints/users.wsdl"); 
        uc.setMarshaller(marshaller);  
        uc.setUnmarshaller(marshaller);
        return uc; 
     }  
}

8.3 Führen Sie den SOAP-Webservice-Client aus

Wir werden eine Klasse mit Hauptmethode definieren, um ein Argument der Benutzer-ID zu übergeben. Unser Client ruft den Webdienst mit übergebenem Argument auf, um uns die Daten zurückzugeben, wenn diese Benutzer-ID in der Datenbank vorhanden war.

9. Fazit

In diesem Artikel haben wir gezeigt, wie Sie einen SOAP-Webdienst erstellen und einen Client erstellen, der denselben SOAP-Webdienst mit Spring Boot nutzt. Der Code dafür ist auf github

verfügbar

10. Referenzen

  1. Tutorial für Spring-Webdienste
  2. Erzeuger und Verbraucher von SOAP-Webdiensten
  3. Nutzung eines Webdienstes in Java und SOAP UI


Java-Tag