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. Casino in Queens - Tickets - JTH Hub
    Find 속초 출장샵 all information about casino in 시흥 출장마사지 Queens. The best 문경 출장마사지 place to watch the action on the go! You can watch 정읍 출장안마 all of our live casino action 과천 출장마사지 through an

    ReplyDelete