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="http://onlinetutorialspoint.com/generated" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://onlinetutorialspoint.com/generated" targetNamespace="http://onlinetutorialspoint.com/generated">
    <wsdl:types>
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://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:

About the Author:

Founder of onlinetutorialspoint.com Love Java, Python, Shell and opensource frameworks. Follow him on twitter and facebook for latest updates.

3 Comments

  1. Daniel July 1, 2021 at 2:58 am - Reply

    Very helpful and clean

  2. anupama August 9, 2021 at 12:57 pm - Reply

    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.

    your application as is working fine.
    but when i used it for my purpose the plug in is not generating any bindings package ,

    i am not sure what i am doing wrong. exactly followed as per your application…

    • chandrashekhar August 9, 2021 at 2:47 pm - Reply

      Hey Anupama, thanks for reaching me. Can you elaborate on the issue you are facing? or if you provide the error logs, that is much helpful for better research on the issue.

Leave A Comment