Spring 4 + SOAP Web Service Producer and Consumer Example with Tomcat
January 02, 2015
This page will provide spring 4 and SOAP web service integration to produce and consume soap request and response using annotation. Spring web service uses contract-first SOAP service which produces flexible web services that can use different manipulated XML payloads. Find some basic feature of spring web service.
1. Spring web service provides loose coupling between contract and implementation.
2. It provides powerful mapping between incoming XML request and any object.
3. Spring web service uses JAXP APIs to handle incoming XML messages.
4. It provides flexible XML marshaling using JAXB 1 and 2, Castor, XMLBeans, JiBX, and XStream.
5. Spring Web service security allows signing SOAP messages, encrypting and decrypting them.
Now find the complete demo to produce and consume the soap web service. In our example, we will cover below points.
Contents
Software Used to Run Example
To run the example we are using below software.1. Java 7
2. Tomcat 8
3. Eclipse
4. Maven
Produce SOAP Web Service
We will create an application that will act as web service for student data. For the given student id, our web service will respond the complete profile of student.Project Configuration in Eclipse for SOAP Web Service Producer
Find the project configuration in eclipse.
Sample XSD file used in Example
Find the sample XSD file being used in the example. On the basis of this file, maven will generate java classes.students.xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://concretepage.com/soap" targetNamespace="http://concretepage.com/soap" elementFormDefault="qualified"> <xs:element name="getStudentRequest"> <xs:complexType> <xs:sequence> <xs:element name="studentId" type="xs:int"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="getStudentResponse"> <xs:complexType> <xs:sequence> <xs:element name="student" type="tns:student"/> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="student"> <xs:sequence> <xs:element name="studentId" type="xs:int"/> <xs:element name="name" type="xs:string"/> <xs:element name="age" type="xs:int"/> <xs:element name="class" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema>
Run the Maven to Resolve JAR Dependency and Generated Classes for XSD file
Maven will resolve the JAR dependency and will produce java classes for the XSD file by its plugin.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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.concretepage.app</groupId> <artifactId>spring4soap</artifactId> <version>1</version> <packaging>war</packaging> <name>Spring 4 Soap</name> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-ws</artifactId> <version>1.2.0.RELEASE</version> </dependency> <dependency> <groupId>wsdl4j</groupId> <artifactId>wsdl4j</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.2.12</version> </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>
1. GetStudentRequest.java
2. GetStudentResponse.java
3. ObjectFactory.java
4. package-info.java
5. Student.java
Sample Data for Output
For the demo, we are populating student profile in a map and providing a method to return student profile for the given student id.StudentUtility.java
package com.concretepage; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Component; import com.concretepage.soap.Student; @Component public class StudentUtility { private Map<Integer,Student> studentMap = new HashMap<Integer,Student>(); public StudentUtility(){ Student s1 = new Student(); s1.setStudentId(1); s1.setName("Ram"); s1.setAge(20); s1.setClazz("ABC"); studentMap.put(1, s1); Student s2 = new Student(); s2.setStudentId(2); s2.setName("Shyam"); s2.setAge(22); s2.setClazz("EFG"); studentMap.put(2, s2); } public Student getStudent(int studentId){ return studentMap.get(studentId); } }
Configuration Class: Use WsConfigurerAdapter , @EnableWs, DefaultWsdl11Definition, XsdSchema
The configuration class should be annotated with @EnableWs that will provide web service configuration. We need to override WsConfigurerAdapter to get required WsConfigurer methods. The bean name for DefaultWsdl11Definition is must because this bean name will be the part of WSDL URL as students.wsdl.@EnableWs : Provides spring web service configuration.
WsConfigurerAdapter : This class is an adapter class that contains only required methods of WsConfigurer.
DefaultWsdl11Definition : Creates SOAP for the given XSD schema.
XsdSchema : Abstraction for XSD schema.
Now find the configuration class.
AppConfig.java
package com.concretepage; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; 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.wsdl.wsdl11.DefaultWsdl11Definition; import org.springframework.xml.xsd.SimpleXsdSchema; import org.springframework.xml.xsd.XsdSchema; @Configuration @EnableWs @ComponentScan("com.concretepage") public class AppConfig extends WsConfigurerAdapter { @Bean(name = "students") public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema studentsSchema) { DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition(); wsdl11Definition.setPortTypeName("StudentsPort"); wsdl11Definition.setLocationUri("/soapws"); wsdl11Definition.setTargetNamespace("http://concretepage.com/soap"); wsdl11Definition.setSchema(studentsSchema); return wsdl11Definition; } @Bean public XsdSchema studentsSchema() { return new SimpleXsdSchema(new ClassPathResource("students.xsd")); } }
WebApplicationInitializer using MessageDispatcherServlet
MessageDispatcherServlet is a servlet that is specific to dispatch web service message. We need to use this class in place of DispatcherServlet for web service. The method setTransformSchemaLocations can be true or false. If true, MessageDispatcherServlet transforms relative address location in XSD to incoming request.WebAppInitializer.java
package com.concretepage; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration.Dynamic; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.ws.transport.http.MessageDispatcherServlet; public class WebAppInitializer implements WebApplicationInitializer { public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(AppConfig.class); ctx.setServletContext(servletContext); MessageDispatcherServlet servlet = new MessageDispatcherServlet(); servlet.setApplicationContext(ctx); servlet.setTransformWsdlLocations(true); Dynamic dynamic = servletContext.addServlet("dispatcher",servlet); dynamic.addMapping("/soapws/*"); dynamic.setLoadOnStartup(1); } }
Endpoint for SOAP Web Service using Annotation
Find the endpoint class for the web service. This classe uses different annotations as below.@Endpoint: Indicates an annotated class for web service end point.
@PayloadRoot: Marks the method to be handler for incoming request.
@ResponsePayload: Bounds the method return type to the response payload.
@RequestPayload : Bounds the method parameter to the request payload.
Find the web service endpoint class.
StudentEndpoint.java
package com.concretepage; 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.concretepage.soap.GetStudentRequest; import com.concretepage.soap.GetStudentResponse; @Endpoint public class StudentEndpoint { private static final String NAMESPACE_URI = "http://concretepage.com/soap"; @Autowired private StudentUtility studentUtility; @PayloadRoot(namespace = NAMESPACE_URI, localPart = "getStudentRequest") @ResponsePayload public GetStudentResponse getStudent(@RequestPayload GetStudentRequest request) { GetStudentResponse response = new GetStudentResponse(); response.setStudent(studentUtility.getStudent(request.getStudentId())); return response; } }
Test SOAP Web Service using SoapUI
Deploy the WAR file in tomcat 8 generated by Maven. The WSDL URL will behttp://localhost:8080/spring4soap-1/soapws/students.wsdl
We can access it in browser directly to get WSDL response. To test in SOAP UI, use a request soap in which we need to provide student id and in response, we will get student profile.

Consume SOAP Web Service
Now we will create a spring application that will consume web service. We need to generate java classes corresponding to producer web service WSDL URL.Project Structure in Eclipse for SOAP Web Service Consumer
Find the project structure in eclipse for SOAP Web Service Consumer.
Maven to Resolve JAR Dependency and Generate Classes for WSDL URL
Find pom.xml that will resolve the JAR dependency and will generate java classes for the given WSDL URL.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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.concretepage.app</groupId> <artifactId>spring4soap</artifactId> <version>1</version> <packaging>jar</packaging> <name>Spring 4 Soap Client</name> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-ws</artifactId> <version>1.2.0.RELEASE</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.2.12</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.jvnet.jaxb2.maven2</groupId> <artifactId>maven-jaxb2-plugin</artifactId> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> <configuration> <schemaLanguage>WSDL</schemaLanguage> <generatePackage>com.concretepage.wsdl</generatePackage> <forceRegenerate>true</forceRegenerate> <schemas> <schema> <url>http://localhost:8080/spring4soap-1/soapws/students.wsdl</url> </schema> </schemas> </configuration> </plugin> </plugins> </build> </project>
1. GetStudentRequest.java
2. GetStudentResponse.java
3. ObjectFactory.java
4. package-info.java
5. Student.java
Create Client Class Using WebServiceGatewaySupport
WebServiceGatewaySupport is a super class that facilitates the sub class to access web service methods. This class has its own WebServiceTemplate that can be fetched by the method getWebServiceTemplate()StudentClient.java
package com.concretepage; import org.springframework.ws.client.core.support.WebServiceGatewaySupport; import org.springframework.ws.soap.client.core.SoapActionCallback; import com.concretepage.wsdl.GetStudentRequest; import com.concretepage.wsdl.GetStudentResponse; public class StudentClient extends WebServiceGatewaySupport { public GetStudentResponse getStudentById(int studentId) { GetStudentRequest request = new GetStudentRequest(); request.setStudentId(studentId); GetStudentResponse response = (GetStudentResponse) getWebServiceTemplate().marshalSendAndReceive( request, new SoapActionCallback("http://localhost:8080/spring4soap-1/soapws/getStudentResponse")); return response; } }
Configuration Class: Use Jaxb2Marshaller
Jaxb2Marshaller is the implementation of GenericMarshaller interface to support JAXB. It is being used here to set context path using setContextPath .ClientAppConfig.java
package com.concretepage; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.oxm.jaxb.Jaxb2Marshaller; @Configuration public class ClientAppConfig { @Bean public Jaxb2Marshaller marshaller() { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); marshaller.setContextPath("com.concretepage.wsdl"); return marshaller; } @Bean public StudentClient studentClient(Jaxb2Marshaller marshaller) { StudentClient client = new StudentClient(); client.setDefaultUri("http://localhost:8080/spring4soap-1/soapws/students.wsdl"); client.setMarshaller(marshaller); client.setUnmarshaller(marshaller); return client; } }
Main Method to Run the Demo
Now test the consuming web service. Here we are passing student id and web service will return student profile.RunSoapClient.java
package com.concretepage; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.concretepage.wsdl.GetStudentResponse; public class RunSoapClient { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(ClientAppConfig.class); ctx.refresh(); StudentClient studentClient = ctx.getBean(StudentClient.class); System.out.println("For Student Id: 1"); GetStudentResponse response = studentClient.getStudentById(1); System.out.println("Name:"+response.getStudent().getName()); System.out.println("Age:"+response.getStudent().getAge()); System.out.println("Class:"+response.getStudent().getClazz()); } }
For Student Id: 1 Name:Ram Age:20 Class:ABC
Note: Find the link for Spring SOAP Web Service example using Spring Boot.
Spring Boot SOAP Web Service Example