By kswaughs | Wednesday, March 15, 2017

Spring Boot Soap Web Service Example

This post explains how to develop a soap based web service with Spring Boot. In this Book Store example, We will create a web service that allows to add books information and get the book information.

Step 1: Maven setup

pom.xml
<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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>
    <groupId>com.kswaughs.spring</groupId>
    <artifactId>spring_boot_soapwebsvc</artifactId>
    <version>1.0</version>
    <packaging>war</packaging>
    <name>spring_boot_soapwebsvc</name>
    <description>Spring Boot SOAP WEB Service Example</description>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
            <version>1.5.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>wsdl4j</groupId>
            <artifactId>wsdl4j</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <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>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Step 2: Create an XML Schema to define the WebService domain. This book store web service provides two operations to add & get Book details.

src/main/resources/books.xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://com/kswaughs/services/bookSvc"
    targetNamespace="http://com/kswaughs/services/bookSvc"
    elementFormDefault="qualified">

    <xs:element name="getBookRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="getBookResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="book" type="tns:book" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="addBookRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="book" type="tns:book" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    
    <xs:element name="addBookResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="status" type="xs:string" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    
    <xs:complexType name="book">
        <xs:sequence>
            <xs:element name="name" type="xs:string" />
            <xs:element name="author" type="xs:string" />
            <xs:element name="price" type="xs:string" />
        </xs:sequence>
    </xs:complexType>
    
</xs:schema>

Step 3: Generate Domain classes based on Schema defined. When you run Maven build, jaxb2-maven-plugin will generate the java files and stores in src/main/java folder.

Step 4: Create a book repository class to store books details and Initialise the list with few books.

BookRepository.java
package com.kswaughs.repo;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import com.kswaughs.services.booksvc.Book;

@Component
public class BookRepository {
    
    private static final List<Book> books = new ArrayList<Book>();

    @PostConstruct
    public void initData() {
        Book book1 = new Book();
        book1.setName("The Family Way");
        book1.setAuthor("Tony Parsons");
        book1.setPrice("10 $");
        
        books.add(book1);

        Book book2 = new Book();
        book2.setName("Count To Ten");
        book2.setAuthor("Karen Rose");
        book2.setPrice("12 $");
        
        books.add(book2);
    }

    public Book findBook(String name) {
        Assert.notNull(name);

        Book result = null;

        for (Book book : books) {
            if (name.equals(book.getName())) {
                result = book;
            }
        }

        return result;
    }
    
    public void addBook(Book book) {
        books.add(book);
    }
}

Step 5: Create BookService EndPoint class to handle the incoming SOAP requests.

BookEndPoint.java
package com.kswaughs.services;

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.kswaughs.repo.BookRepository;
import com.kswaughs.services.booksvc.AddBookRequest;
import com.kswaughs.services.booksvc.AddBookResponse;
import com.kswaughs.services.booksvc.GetBookRequest;
import com.kswaughs.services.booksvc.GetBookResponse;

@Endpoint
public class BookEndPoint {
    
    private static final String NAMESPACE_URI = "http://com/kswaughs/services/bookSvc";

    private BookRepository bookRepository;

    @Autowired
    public BookEndPoint(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }

    // To handle getBookRequest
    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "getBookRequest")
    @ResponsePayload
    public GetBookResponse getBook(@RequestPayload GetBookRequest request) {
        GetBookResponse response = new GetBookResponse();
        response.setBook(bookRepository.findBook(request.getName()));

        return response;
    }
    
    // To handle addBookRequest
    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "addBookRequest")
    @ResponsePayload
    public AddBookResponse addBook(@RequestPayload AddBookRequest request) {
        AddBookResponse response = new AddBookResponse();
        bookRepository.addBook(request.getBook());
        response.setStatus("SUCCESS");
        return response;
    }
}

Step 6: Configure Web Service Spring beans

SpringWebConfig.java
package com.kswaughs.config;

import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
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;

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

    @Bean(name = "books")
    public DefaultWsdl11Definition defaultBookWsdl11Definition(XsdSchema countriesSchema) {
        DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
        wsdl11Definition.setPortTypeName("BooksPort");
        wsdl11Definition.setLocationUri("/ws");
        wsdl11Definition.setTargetNamespace("http://com/kswaughs/services/bookSvc");
        wsdl11Definition.setSchema(booksSchema());
        return wsdl11Definition;
    }

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

Step 7: Create Spring Boot Main Application Class

BootApp.java
package com.kswaughs.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan({ "com.kswaughs.*" })
public class BootApp {
    
    public static void main(String[] args) {
        SpringApplication.run(BootApp.class, args);
    }

}

Step 8: Define application Context path & port in application.properties

src/main/resources/application.properties
server.contextPath=/MyApp
server.port=8088

Testing the Application

WSDL Url : http://localhost:8088/MyApp/ws/books.wsdl

SOAP URL : http://localhost:8088/MyApp/ws

Test 1 : addBookRequest

SOAP Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:book="http://com/kswaughs/services/bookSvc">
   <soapenv:Header/>
   <soapenv:Body>
      <book:addBookRequest>
         <book:book>
            <book:name>Revolution 2020</book:name>
            <book:author>Chetan Bhagat</book:author>
            <book:price>11 $</book:price>
         </book:book>
      </book:addBookRequest>
   </soapenv:Body>
</soapenv:Envelope>

SOAP Response:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <ns2:addBookResponse xmlns:ns2="http://com/kswaughs/services/bookSvc">
         <ns2:status>SUCCESS</ns2:status>
      </ns2:addBookResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Test 2 : getBookRequest

SOAP Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:book="http://com/kswaughs/services/bookSvc">
   <soapenv:Header/>
   <soapenv:Body>
      <book:getBookRequest>
         <book:name>Revolution 2020</book:name>
      </book:getBookRequest>
   </soapenv:Body>
</soapenv:Envelope>

SOAP Response:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <ns2:getBookResponse xmlns:ns2="http://com/kswaughs/services/bookSvc">
         <ns2:book>
            <ns2:name>Revolution 2020</ns2:name>
            <ns2:author>Chetan Bhagat</ns2:author>
            <ns2:price>11 $</ns2:price>
         </ns2:book>
      </ns2:getBookResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Recommend this on


2 comments:

  1. Nice example.

    What if We want to send request to web service using soap header like username & password?

    Do you have any example for that case?

    Thanks
    hendisantika@yahoo.co.id

    ReplyDelete
  2. The effectiveness of IEEE Project Domains depends very much on the situation in which they are applied. In order to further improve IEEE Final Year Project Domains practices we need to explicitly describe and utilise our knowledge about software domains of software engineering Final Year Project Domains for CSE technologies. This paper suggests a modelling formalism for supporting systematic reuse of software engineering technologies during planning of software projects and improvement programmes in Project Centers in Chennai for CSE.

    Spring Framework has already made serious inroads as an integrated technology stack for building user-facing applications. Spring Framework Corporate TRaining the authors explore the idea of using Java in Big Data platforms.
    Specifically, Spring Framework provides various tasks are geared around preparing data for further analysis and visualization. Spring Training in Chennai

    ReplyDelete