This post explains how to consume a soap web service with Spring Boot using org.springframework.ws.client.core.WebServiceTemplate class.
In this example, we will call Book Store web service which is already explained in the following post.
Spring Boot Soap Web Service Example
Step 1: Maven setup
<?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> <groupId>com.kswaughs.spring</groupId> <artifactId>spring-boot-soap-service-client</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-boot-soap-service-client</name> <description>Demo project for Spring Boot SOAP Web service Client</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <maven-jaxb2-plugin.version>0.13.2</maven-jaxb2-plugin.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>${maven-jaxb2-plugin.version}</version> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> <configuration> <schemaDirectory> ${project.basedir}/src/main/resources/wsdl </schemaDirectory> <schemaIncludes> <include>*.wsdl</include> </schemaIncludes> </configuration> </plugin> </plugins> </build> </project>
Step 2: To consume a web service, we need a WSDL file. Copy your WSDL file to resources folder.
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch="http://com/kswaughs/services/bookSvc" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://com/kswaughs/services/bookSvc" targetNamespace="http://com/kswaughs/services/bookSvc"> <wsdl:types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://com/kswaughs/services/bookSvc"> <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> </wsdl:types> <wsdl:message name="getBookRequest"> <wsdl:part element="tns:getBookRequest" name="getBookRequest"> </wsdl:part> </wsdl:message> <wsdl:message name="addBookRequest"> <wsdl:part element="tns:addBookRequest" name="addBookRequest"> </wsdl:part> </wsdl:message> <wsdl:message name="addBookResponse"> <wsdl:part element="tns:addBookResponse" name="addBookResponse"> </wsdl:part> </wsdl:message> <wsdl:message name="getBookResponse"> <wsdl:part element="tns:getBookResponse" name="getBookResponse"> </wsdl:part> </wsdl:message> <wsdl:portType name="BooksPort"> <wsdl:operation name="getBook"> <wsdl:input message="tns:getBookRequest" name="getBookRequest"> </wsdl:input> <wsdl:output message="tns:getBookResponse" name="getBookResponse"> </wsdl:output> </wsdl:operation> <wsdl:operation name="addBook"> <wsdl:input message="tns:addBookRequest" name="addBookRequest"> </wsdl:input> <wsdl:output message="tns:addBookResponse" name="addBookResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="BooksPortSoap11" type="tns:BooksPort"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="getBook"> <soap:operation soapAction="" /> <wsdl:input name="getBookRequest"> <soap:body use="literal" /> </wsdl:input> <wsdl:output name="getBookResponse"> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="addBook"> <soap:operation soapAction="" /> <wsdl:input name="addBookRequest"> <soap:body use="literal" /> </wsdl:input> <wsdl:output name="addBookResponse"> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="BooksPortService"> <wsdl:port binding="tns:BooksPortSoap11" name="BooksPortSoap11"> <soap:address location="http://localhost:8088/MyApp/ws" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
Step 3: Generate Domain classes based on Schema defined. When you run Maven build, maven-jaxb2-plugin will generate the java files and stores in target/generated-sources/xjc folder. Configure this folder as source folder in your eclipse IDE.
Step 4: Create Web Service Client Configuration class.
package com.kswaughs.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.oxm.jaxb.Jaxb2Marshaller; import org.springframework.ws.client.core.WebServiceTemplate; @Configuration public class WebSvcClientConfig { @Value("${books.svc.url}") private String url; @Bean Jaxb2Marshaller jaxb2Marshaller() { Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller(); jaxb2Marshaller.setContextPath("com.kswaughs.services.booksvc"); return jaxb2Marshaller; } @Bean public WebServiceTemplate webServiceTemplate() { WebServiceTemplate webServiceTemplate = new WebServiceTemplate(); webServiceTemplate.setMarshaller(jaxb2Marshaller()); webServiceTemplate.setUnmarshaller(jaxb2Marshaller()); webServiceTemplate.setDefaultUri(url); return webServiceTemplate; } }
Step 5: Create a Service Client class which will consume the web service through above configured WebServiceTemplate class.
package com.kswaughs.services; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.ws.client.core.WebServiceTemplate; import com.kswaughs.services.booksvc.AddBookRequest; import com.kswaughs.services.booksvc.AddBookResponse; import com.kswaughs.services.booksvc.Book; import com.kswaughs.services.booksvc.GetBookRequest; import com.kswaughs.services.booksvc.GetBookResponse; import com.kswaughs.services.booksvc.ObjectFactory; @Component public class BookServiceClient { private static final Logger LOGGER = LoggerFactory.getLogger(BookServiceClient.class); @Autowired private WebServiceTemplate webServiceTemplate; public String addBook(String name, String author, String price) { ObjectFactory factory = new ObjectFactory(); AddBookRequest req = factory.createAddBookRequest(); Book book = new Book(); book.setAuthor(author); book.setName(name); book.setPrice(price); req.setBook(book); LOGGER.info("Client sending book[Name={},", book.getName()); AddBookResponse resp = (AddBookResponse) webServiceTemplate.marshalSendAndReceive(req); LOGGER.info("Client received status='{}'", resp.getStatus()); return resp.getStatus(); } public Book getBook(String name) { ObjectFactory factory = new ObjectFactory(); GetBookRequest req = factory.createGetBookRequest(); req.setName(name); LOGGER.info("Client sending book[Name={},", name); GetBookResponse resp = (GetBookResponse) webServiceTemplate.marshalSendAndReceive(req); LOGGER.info("Client received book='{}'", resp.getBook()); return resp.getBook(); } }
Step 6: To test this application, I am creating a sample class which will reads the user entered commands from console and calls the service client methods.
package com.kswaughs.services; import java.util.Arrays; import java.util.Scanner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import com.kswaughs.services.booksvc.Book; @Component public class BookCommandLineListener { private static final Logger LOGGER = LoggerFactory .getLogger(BookCommandLineListener.class); @Autowired private BookServiceClient bookSvcClient; @Scheduled(fixedDelay=1000) public void run() throws Exception { try (Scanner scanner = new Scanner(System.in)) { while (true) { LOGGER.info("Enter your command"); String text = scanner.nextLine(); LOGGER.info("you entered :{}", text); String[] args = text.split("\\s+"); LOGGER.info("args :{}", Arrays.toString(args)); if ("ADD".equalsIgnoreCase(args[0])) { String name = args[1]; String author = args[2]; String price = args[3]; String status = bookSvcClient.addBook(name, author, price); LOGGER.info("Book Added Status :{}", status); } else if ("GET".equalsIgnoreCase(args[0])) { String name = args[1]; Book book = bookSvcClient.getBook(name); if(book != null) { LOGGER.info("GET Book Details : Name:{}, Author:{}, Price:{}", book.getName(), book.getAuthor(), book.getPrice()); } } else { LOGGER.info("Invalid Command."); } } } } }
Step 7: Create Spring Boot Main Application Class
package com.kswaughs; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class SpringBootSoapServiceClientApplication { public static void main(String[] args) { SpringApplication.run(SpringBootSoapServiceClientApplication.class, args); } }
Step 8: Configure web service url in application.properties
books.svc.url=http://localhost:8088/MyApp/ws
Testing the Application
2017-12-01 11:19:13.376 INFO 10440 --- [pool-1-thread-1] c.k.services.BookCommandLineListener : Enter your command ADD SpringGuide kswaughs 10 2017-12-01 11:20:27.922 INFO 10440 --- [pool-1-thread-1] c.k.services.BookCommandLineListener : you entered :ADD SpringGuide kswaughs 10 2017-12-01 11:20:27.922 INFO 10440 --- [pool-1-thread-1] c.k.services.BookCommandLineListener : args :[ADD, SpringGuide, kswaughs, 10] 2017-12-01 11:20:27.922 INFO 10440 --- [pool-1-thread-1] com.kswaughs.services.BookServiceClient : Client sending book[Name=SpringGuide, 2017-12-01 11:20:28.930 INFO 10440 --- [pool-1-thread-1] com.kswaughs.services.BookServiceClient : Client received status='SUCCESS' 2017-12-01 11:20:28.930 INFO 10440 --- [pool-1-thread-1] c.k.services.BookCommandLineListener : Book Added Status :SUCCESS
2017-12-01 11:20:28.930 INFO 10440 --- [pool-1-thread-1] c.k.services.BookCommandLineListener : Enter your command GET SpringGuide 2017-12-01 11:20:43.711 INFO 10440 --- [pool-1-thread-1] c.k.services.BookCommandLineListener : you entered :GET SpringGuide 2017-12-01 11:20:43.711 INFO 10440 --- [pool-1-thread-1] c.k.services.BookCommandLineListener : args :[GET, SpringGuide] 2017-12-01 11:20:43.720 INFO 10440 --- [pool-1-thread-1] com.kswaughs.services.BookServiceClient : Client sending book[Name=SpringGuide, 2017-12-01 11:20:43.740 INFO 10440 --- [pool-1-thread-1] com.kswaughs.services.BookServiceClient : Client received book='com.kswaughs.services.booksvc.Book@fa6b61e' 2017-12-01 11:20:43.740 INFO 10440 --- [pool-1-thread-1] c.k.services.BookCommandLineListener : GET Book Details : Name:SpringGuide, Author:kswaughs, Price:10
2017-12-01 11:20:43.740 INFO 10440 --- [pool-1-thread-1] c.k.services.BookCommandLineListener : Enter your command ABCD 2017-12-01 11:20:56.944 INFO 10440 --- [pool-1-thread-1] c.k.services.BookCommandLineListener : you entered :ABCD 2017-12-01 11:20:56.944 INFO 10440 --- [pool-1-thread-1] c.k.services.BookCommandLineListener : args :[ABCD] 2017-12-01 11:20:56.956 INFO 10440 --- [pool-1-thread-1] c.k.services.BookCommandLineListener : Invalid Command.
Thanks, nice post
ReplyDeleteGreat casino, ever casinos online you can safely put the top ten, with the new year already playing. At first I didn’t enter the topic as it is not hung with all sorts of bells and whistles I used to, but over time you realize that only good gaming games, bonuses and timely payments are needed in the casino, everything else interferes and distracts.
ReplyDeleteThe 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.
ReplyDeleteSpring 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