Different Ways to Create Spring Boot SOAP Client

Different Ways to Create Spring Boot SOAP Client thumbnail
95K
By Dhiraj 26 February, 2019

This article is about consuming SOAP web services through a Spring Boot app. We will be creating a sample spring boot SOAP client to consume SOAP web services using the maven plugins. We will be demonstrating the client generation process using 2 different maven plugins - maven-jaxb2-plugin and cxf-codegen-plugin. Once, the stubs are generated, we will be using WebServiceTemplate to marshal our request and response.

As we know, there are 2 ways to go with SOAP - top-down web service and a bottom-up web service. Here, in this article, we won't be discussing about generating any .wsdl file instead we will be using an existing BLZService wsdl file. The same .wsdl file can be downloaded from here. We will import this WSDL file in our local workspace and generate stubs out of it using maven plugin and create spring boot SOAP client to consume these web services. In next aricle, we will be discussing the exception handling in SOAP web services.

Generating Spring Boot Starter Project

First, let us generate our sample spring boot app from start.spring.io. We have selected 2 dependencies for this web and web services as shown below. The web is required just to expose endpoint for testing purpose whereas the web services dependency provides all required artifacts related to SOAP web services.

spring-boot-soap-client-project-generation

Maven JAXB2 Plugin Config

As we mentioned earlier that we will be demonstrating usage of 2 different plugins to generate the stub, let us start with JAXB2 plugin first. Below is the maven plugin configuration that is required to generate stubs from local wsdl file. We have downloaded the wsdl file and placed inside wsdl directory at src/main/resources/wsdl.

<plugin>
	<groupId>org.jvnet.jaxb2.maven2</groupId>
	<artifactId>maven-jaxb2-plugin</artifactId>
	<version>0.14.0</version>
	<executions>
		<execution>
			<goals>
				<goal>generate</goal>
			</goals>
		</execution>
	</executions>
	<configuration>
		<generatePackage>com.devglan.springbootsoapclient.generated.blz</generatePackage>
		<generateDirectory>${project.basedir}/src/main/java</generateDirectory>
		<schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory>
		<schemaIncludes>
			<include>*.wsdl</include>
		</schemaIncludes>
	</configuration>
</plugin>

generatePackage - Package location where stubs will be generated. In our case it is - com.devglan.springbootsoapclient.generated.blz

generateDirectory -Directory where stubs will be generated. In our case it is - src/main/java

schemaDirectory - WSDl location. In our case it is src/main/resources/wsdl

Now, if you run the maven command mvn clean install with below project structure and above maven configuration, the stubs will be generated inside the package com.devglan.springbootsoapclient.generated.blz

spring-boot-soap-client-project-strct

Spring Boot Marshaller and Unmarshaller Config

Now let us define our bean configuration for Marshaller and Unmarshaller using Jaxb2Marshaller. Here, we have configured our base package where our stubs are generated and this Marshaller and Unmarshaller will be used by WebServiceGatewaySupport during marshalling and unmarshalling.

BeanConfig.java
package com.devglan.springbootsoapclient.config;

import com.devglan.springbootsoapclient.BlzServiceAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;

@Configuration
public class BeanConfig {

	@Bean
	public Jaxb2Marshaller marshaller() {
		Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
		marshaller.setContextPath("com.devglan.springbootsoapclient.generated.blz");
		return marshaller;
	}

	@Bean
	public BlzServiceAdapter soapConnector(Jaxb2Marshaller marshaller) {
		BlzServiceAdapter client = new BlzServiceAdapter();
		client.setDefaultUri("http://www.thomas-bayer.com/axis2/services/BLZService");
		client.setMarshaller(marshaller);
		client.setUnmarshaller(marshaller);
		return client;
	}

}

BlzServiceAdapter Implementation

This adaptr will actually invoke the Blz SOAP web service. getBank() accepts two arguments URL and the payload and makes use of WebServiceTemplate to invoke the web service. You can visit my another article to add custom header in the SOAP request.

BlzServiceAdapter.java
package com.devglan.springbootsoapclient;

import com.devglan.springbootsoapclient.generated.blz.GetBankResponseType;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;

import javax.xml.bind.JAXBElement;

public class BlzServiceAdapter extends WebServiceGatewaySupport {

	public GetBankResponseType getBank(String url, Object request){
		JAXBElement res = (JAXBElement) getWebServiceTemplate().marshalSendAndReceive(url, request);
		return res.getValue();
	}
}

Above implementation is a very simple client implementation. In real time, we need to take care of security and password authentication details in the header. In the next article, we will be discussing about adding custom header in the SOAP request with Spring.

Spring Boot Controller

This controller is only to expose a REST endpoint that accepts code as an input from user and invoke the adapter class getBank(). This is only for testing purpose. You can also invoke this getBank() method using command line.

@RestController
@RequestMapping("/")
public class BlzController {

    @Autowired
    private BlzServiceAdapter blzServiceAdapter;

    @GetMapping
    public DetailsType sum(@RequestParam String code){
        ObjectFactory objectFactory = new ObjectFactory();
        GetBankType type = new GetBankType();
        type.setBlz(code);
        GetBankResponseType response =  blzServiceAdapter.getBank("http://www.thomas-bayer.com/axis2/services/BLZService", objectFactory.createGetBank(type));
        return response.getDetails();
    }
}

Running Spring Boot App

To boostrap our spring app, we have below SpringBootSoapClientApplication.java defined. We will run the below class as a java program.

@SpringBootApplication
public class SpringBootSoapClientApplication {

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

Now, we can hit the URL http://localhost:8080/?code=46062817. Internally, the BLZ SOAP web services will be called and below response can be seen in the browser.

spring-boot-soap-client-response

Maven CXF Codegen Plugin Config

Following is the maven plugin conffiguration for CXF Codegen. You can include as many wsdl file you want using wsdlOption.

<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
	<version>3.2.4</version>
</dependency>
<plugin>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-codegen-plugin</artifactId>
	<version>3.2.4</version>
	<executions>
		<execution>
			<id>generate-sources</id>
			<phase>generate-sources</phase>
			<configuration>
				<sourceRoot>${basedir}/src/main/java/com/devglan/springbootsoapclient/generated/cxf/</sourceRoot>
				<wsdlOptions>
					<wsdlOption>
						<wsdl>${basedir}/src/main/resources/wsdl/blzservice.wsdl</wsdl>
					</wsdlOption>
				</wsdlOptions>
			</configuration>
			<goals>
				<goal>wsdl2java</goal>
			</goals>
		</execution>
	</executions>
</plugin>

Below is the complete pom.xml

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.1.2.RELEASE</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.devglan</groupId>
<artifactId>spring-boot-soap-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-soap-client</name>
<description>Demo project for Spring Boot</description>

<properties>
	<java.version>1.8</java.version>
</properties>

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web-services</artifactId>
	</dependency>

	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
		<version>3.2.4</version>
	</dependency>

	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-codegen-plugin</artifactId>
		<version>3.2.4</version>
	</dependency>
</dependencies>

<build>
	<plugins>
		<plugin>
			<groupId>org.jvnet.jaxb2.maven2</groupId>
			<artifactId>maven-jaxb2-plugin</artifactId>
			<version>0.14.0</version>
			<executions>
				<execution>
					<goals>
						<goal>generate</goal>
					</goals>
				</execution>
			</executions>
			<configuration>
				<generatePackage>com.devglan.springbootsoapclient.generated.blz</generatePackage>
				<generateDirectory>${project.basedir}/src/main/java</generateDirectory>
				<schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory>
				<schemaIncludes>
					<include>*.wsdl</include>
				</schemaIncludes>
			</configuration>
		</plugin>
		<!--<plugin>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-codegen-plugin</artifactId>
			<version>3.2.4</version>
			<executions>
				<execution>
					<id>generate-sources</id>
					<phase>generate-sources</phase>
					<configuration>
						<sourceRoot>${basedir}/src/main/java/com/devglan/springbootsoapclient/generated/cxf/</sourceRoot>
						<wsdlOptions>
							<wsdlOption>
								<wsdl>${basedir}/src/main/resources/wsdl/blzservice.wsdl</wsdl>
							</wsdlOption>
						</wsdlOptions>
					</configuration>
					<goals>
						<goal>wsdl2java</goal>
					</goals>
				</execution>
			</executions>
		</plugin>-->
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>

</project>

Conclusion

In this article, we discussed about consuming SOAP web services through a Spring Boot app. We created a sample spring boot SOAP client to consume SOAP web services using the maven plugins. We demonstrated the client generation process using 2 different maven plugins - maven-jaxb2-plugin and cxf-codegen-plugin

Share

If You Appreciate This, You Can Consider:

We are thankful for your never ending support.

About The Author

author-image
A technology savvy professional with an exceptional capacity to analyze, solve problems and multi-task. Technical expertise in highly scalable distributed systems, self-healing systems, and service-oriented architecture. Technical Skills: Java/J2EE, Spring, Hibernate, Reactive Programming, Microservices, Hystrix, Rest APIs, Java 8, Kafka, Kibana, Elasticsearch, etc.

Further Reading on Spring Boot