In this tutorial, we are going to see how to implement a simple Spring Boot SOAP Consumer Example.

Spring Boot SOAP Consumer:

As part of this example, I am going to consume a SOAP web service; you can follow our previous tutorials to get it.

Pre-requisites:

  • To run the Spring Boot SOAP client – Initially, you should have your running SOAP web service on your local or remote machine.
  • If you do not have in your local, you can follow our previous article on Spring boot SOAP web service.
  • Take the WSDL file handy to build java classes

Technologies:

  • Spring Boot Starter Web Service 2.1.6 RELEASE
  • Java 8
  • Maven
  • Maven Javb2 plugin

Spring Boot SOAP Client Example:

Create a Spring boot application with the following structure.

Application Structure:

Spring Boot SOAP Consumer Example-min

Project Dependencies:

This application requires a single dependency – spring-boot-starter-web-service

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

Required Maven Plugin:

Add the below maven jaxb2 plugin in pom.xml to generate the java binding classes using WSDL file.

pom.xml
<plugin>
        <groupId>org.jvnet.jaxb2.maven2</groupId>
        <artifactId>maven-jaxb2-plugin</artifactId>
        <version>0.13.2</version>
        <executions>
          <execution>
            <goals>
              <goal>generate</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <generatePackage>com.onlinetutorialspoint.soap.bindings</generatePackage>
          <generateDirectory>${project.basedir}/src/main/java</generateDirectory>
          <schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory>
          <schemaIncludes>
            <include>*.wsdl</include>
          </schemaIncludes>
        </configuration>
      </plugin>

Complete pom.xml:

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <groupId>com.onlinetutorialspoint</groupId>
  <artifactId>Spring-Boot-SOAP-Consumer-Example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>Spring-Boot-SOAP-Consumer-Example</name>
  <description>Spring Boot SOAP Consumer Example</description>
  <properties>
    <java.version>1.8</java.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web-services</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.jvnet.jaxb2.maven2</groupId>
        <artifactId>maven-jaxb2-plugin</artifactId>
        <version>0.13.2</version>
        <executions>
          <execution>
            <goals>
              <goal>generate</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <generatePackage>com.onlinetutorialspoint.soap.bindings</generatePackage>
          <generateDirectory>${project.basedir}/src/main/java</generateDirectory>
          <schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory>
          <schemaIncludes>
            <include>*.wsdl</include>
          </schemaIncludes>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Configure the WSDL file:

Take the WSDL file from the SOAP web service provider. In our case, we have our SOAP web service running on our machine, and here is the WSDL.

Create a file under resources/wsdl folder with the name of items.wsdl and paste the above content init.

/resources/wsdl/items.wsdl
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch="https://onlinetutorialspoint.com/generated" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="https://onlinetutorialspoint.com/generated" targetNamespace="https://onlinetutorialspoint.com/generated">
    <wsdl:types>
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="https://onlinetutorialspoint.com/generated">
            <xs:element name="ItemRequest">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="id" type="xs:int"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="ItemResponse">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="id" type="xs:int"/>
                        <xs:element name="name" type="xs:string"/>
                        <xs:element name="category" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="ItemRequest">
        <wsdl:part element="tns:ItemRequest" name="ItemRequest"> </wsdl:part>
    </wsdl:message>
    <wsdl:message name="ItemResponse">
        <wsdl:part element="tns:ItemResponse" name="ItemResponse"> </wsdl:part>
    </wsdl:message>
    <wsdl:portType name="Item">
        <wsdl:operation name="Item">
            <wsdl:input message="tns:ItemRequest" name="ItemRequest"> </wsdl:input>
            <wsdl:output message="tns:ItemResponse" name="ItemResponse"> </wsdl:output>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="ItemSoap11" type="tns:Item">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="Item">
            <soap:operation soapAction=""/>
            <wsdl:input name="ItemRequest">
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output name="ItemResponse">
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="ItemService">
        <wsdl:port binding="tns:ItemSoap11" name="ItemSoap11">
            <soap:address location="http://localhost:8080/ws"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

After this step, you just build the application, then you could see the binding classes under src/main/soap/bindings package. Because we configured this under the plugins section in pom.xml.

Let’s have a look at binding classes:

Note: Any modifications on these binding classes will be lost upon the recompilation of the application.

ItemRequest:

src/java/com/onlinetutorialspoint/soap/bindings/ItemRequest.java
package com.onlinetutorialspoint.soap.bindings;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "id"
})
@XmlRootElement(name = "ItemRequest")
public class ItemRequest {

    protected int id;

    public int getId() {
        return id;
    }

    public void setId(int value) {
        this.id = value;
    }

}

ItemResponse:

src/java/com/onlinetutorialspoint/soap/bindings/ItemResponse.java
package com.onlinetutorialspoint.soap.bindings;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "id",
    "name",
    "category"
})
@XmlRootElement(name = "ItemResponse")
public class ItemResponse {

    protected int id;
    @XmlElement(required = true)
    protected String name;
    @XmlElement(required = true)
    protected String category;
    
    public int getId() {
        return id;
    }
    
    public void setId(int value) {
        this.id = value;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String value) {
        this.name = value;
    }
    
    public String getCategory() {
        return category;
    }
    
    public void setCategory(String value) {
        this.category = value;
    }

}

ObjectFactory:

src/java/com/onlinetutorialspoint/soap/bindings/ObjectFactory.java
package com.onlinetutorialspoint.soap.bindings;

import javax.xml.bind.annotation.XmlRegistry;

@XmlRegistry
public class ObjectFactory {
    
    public ObjectFactory() {
    }

    public ItemRequest createItemRequest() {
        return new ItemRequest();
    }

    public ItemResponse createItemResponse() {
        return new ItemResponse();
    }

}

Application.properties

Making this application port to 8081. As I have a SOAP service running on 8080 port.

/resources/application.properties
server.port=8081

Create Soap Configuration:

Creating Jaxb2Marshaller object and given the binding classes to scan while loading the application.

/config/SoapConfig.java
package com.onlinetutorialspoint.config;

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

@Configuration
public class SoapConfig {

    @Bean
    public Jaxb2Marshaller marshaller(){
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        jaxb2Marshaller.setPackagesToScan("com.onlinetutorialspoint.soap.bindings");
        return jaxb2Marshaller;
    }
}

Creating a SOAP client:

The SOAP client class, which is responsible for communicating with the SOAP service and getting the response using WebServiceTemplate object.

client/SoapClient.java
package com.onlinetutorialspoint.client;

import com.onlinetutorialspoint.soap.bindings.ItemRequest;
import com.onlinetutorialspoint.soap.bindings.ItemResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.stereotype.Service;
import org.springframework.ws.client.core.WebServiceTemplate;

@Service
public class SoapClient {

    @Autowired
    private Jaxb2Marshaller jaxb2Marshaller;

    private WebServiceTemplate webServiceTemplate;

    public ItemResponse getItemInfo(ItemRequest itemRequest){
        webServiceTemplate = new WebServiceTemplate(jaxb2Marshaller);
        return (ItemResponse) webServiceTemplate.marshalSendAndReceive("http://localhost:8080/ws",itemRequest);
    }
}

On the above example, we have given the WSDL URI (http://localhost:8080/ws) to marshalSendAndReceive method. As I am running the service application on my local, I gave the local WSDL URI. If you wanted to access any remote WSDL, you could provide the remote URI here.

Creating a Rest Controller:

I am creating a RestController to access this SOAP client.

controller/ItemController.java
package com.onlinetutorialspoint.controller;

import com.onlinetutorialspoint.client.SoapClient;
import com.onlinetutorialspoint.soap.bindings.ItemRequest;
import com.onlinetutorialspoint.soap.bindings.ItemResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ItemController {
    @Autowired
    SoapClient soapClient;

    @PostMapping("/item")
    public ItemResponse item(@RequestBody ItemRequest itemRequest){
        return soapClient.getItemInfo(itemRequest);
    }
}

Run the Application:

Terminal
$mvn clean install
$mvn spring-boot:run
[INFO] --- spring-boot-maven-plugin:2.1.6.RELEASE:run (default-cli) @ Spring-Boot-SOAP-Consumer-Example ---

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.6.RELEASE)

2019-07-27 00:36:29.644  INFO 23148 --- [           main] SpringBootSoapConsumerExampleApplication : Starting SpringBootSoapConsumerExampleApplication on DESKTOP-RN4SMHT with PID 23148 (
D:\work\Spring-Boot-SOAP-Consumer-Example\target\classes started by Lenovo in D:\work\Spring-Boot-SOAP-Consumer-Example)
2019-07-27 00:36:29.657  INFO 23148 --- [           main] SpringBootSoapConsumerExampleApplication : No active profile set, falling back to default profiles: default
2019-07-27 00:36:31.723  INFO 23148 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.ws.config.annotation.DelegatingWsConfiguration' of type [or
g.springframework.ws.config.annotation.DelegatingWsConfiguration$$EnhancerBySpringCGLIB$$c255fca6] is not eligible for getting processed by all BeanPostProcessors (for example: not eligi
ble for auto-proxying)
2019-07-27 00:36:31.797  INFO 23148 --- [           main] .w.s.a.s.AnnotationActionEndpointMapping : Supporting [WS-Addressing August 2004, WS-Addressing 1.0]
2019-07-27 00:36:32.760  INFO 23148 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8081 (http)
2019-07-27 00:36:32.811  INFO 23148 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
....
....
Note: Make sure your SOAP web service also running.

Access the Application from Postman:

Spring Boot SOAP Client Example-min

Done!

References:

Download Source from GIT: