How to remove files from Git commit



Use the below command to change the position of HEAD of your branch.

git reset --soft HEAD^ 

or

git reset --soft HEAD~1

If you want to modify the content of the file. Edit the file directly. Alterantively if you want to remove the file from the commit then use below command.

git reset HEAD path/to/unwanted_file

Now commit again, you can even re-use the same commit message:

git commit -c ORIG_HEAD

How to configure passwordless ssh and scp



Create pair of private key and public key

Open the terminal and then use ssh-keygen to generate the pair of keys

By default system will generate the keys with name id_rsa & id_rsa.pub. If you want to generate with custom name then enter the file name when it prompts.

passphrase will act as password for your key to avoid misuse, you can keep it blank also.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ ssh-keygen -t rsa**

Generating public/private rsa key pair.
Enter file in which to save the key (/home/author/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/author/.ssh/id_rsa.
Your public key has been saved in /home/ec2-user/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:7B2G20AHF7PFHIACElEAzEO+i293wReZI49T7MMH1ns author@tutorialflix
The key's randomart image is:
+---[RSA 2048]----+
|=o==o. ..==o. |
|.+ . . .o +o |
| .. o.+o |
| . .oXo. |
| . . OS+o. |
|. . =.**o.E |
|.. +ooo. |
| .. . . |
| ... . |
+----[SHA256]-----+

Upload Your Public Key to Remote Linux Server

You can upload the key using ssh-copy-id command, which is shipped by the openssh-client package.

1
2
3
4
5
6
7
8
9
ssh-copy-id remote-user@server-ip
**enter password**

/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
remote-user@server-ip's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'remote-user@server-ip'"
and check to make sure that only the key(s) you wanted were added.

The public key is stored in .ssh/authorized_keys file under the remote user’s home directory. Now ssh into the remote server and you will be able to login without password

How to implement security in SOAP webservice using Spring-WS



Overview

In this tutorial, we’ll see how to implement security in SOAP webservice. Normally we use two types of security in SOAP webservice.

1) WS-Security using policies
2) Basic Authentication

For this tutorial, we’ll implement the policy based approach and all the configuration will be annoation-based.

Pre-requisties

  1. JDK 1.8 +
  2. Maven
  3. IDE

Approach

SOAP services can be developed with two methods

  1. Contract First : Define WSDL and Schema before writing any code.
  2. Contract Last: Auto-generate the WSDL and schemas from the java classes.

Spring-ws only supports the contract-first approach

Project setup

You can clone this project from Github to kick start the project

Create a maven project and add the following dependencies in the pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
</dependencies>

Schema Design

Contract first approach requires us to define the schema. And then we’ll use Spring-ws auto-generate WSDL out of the schema.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://spring.tutorialflix.com/types/v1"
xmlns:tns="http://spring.tutorialflix.com/types/v1" elementFormDefault="qualified">
<xs:element name="createCustomerRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="customerName">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
<xs:whiteSpace value="collapse" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="customerAge">
<xs:simpleType>
<xs:restriction base="xs:integer" />
</xs:simpleType>
</xs:element>
<xs:element name="customerCity">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
<xs:whiteSpace value="collapse" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="customerPhoneNumber">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
<xs:whiteSpace value="collapse" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="createCustomerResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="customerID" type="xs:integer" />
<xs:element name="details" type="xs:string" />
<xs:element name="status" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="createCustomerFault">
<xs:complexType>
<xs:sequence>
<xs:element name="errorMessage" type="xs:normalizedString" />
<xs:element name="errorCode" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Generate Java Classes

Now, we’ll jaxb2-maven-plugin to generate the java classes from the schema. Add the below plugin in your pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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>
  • schemaDirectory : location of the schema
  • outputDirectory: where we want our java classes.
  • clearOutputDir : making this true will delete the classes every time you compile the project

Now, we’ll generate the classes by issuing a following maven command.

$ mvn clean install

Now you can see the auto-generated classes in you project folder.

Setup Endpoint

Now, we’ll setup an endpoint in our Java code to serve the request. Create a class and annotate with @Endpoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.tutorialflix.spring.ws.endpoint;

import java.math.BigInteger;

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.tutorialflix.spring.types.v1.CreateCustomerRequest;
import com.tutorialflix.spring.types.v1.CreateCustomerResponse;

@Endpoint
public class CustomerServiceEndpoint {

@ResponsePayload
@PayloadRoot(localPart = "createCustomerRequest", namespace = "http://spring.tutorialflix.com/types/v1")
public CreateCustomerResponse createCustomer(@RequestPayload CreateCustomerRequest request) {

CreateCustomerResponse response = new CreateCustomerResponse();
response.setCustomerID(BigInteger.ONE);
response.setDetails(request.getCustomerName() + " " + request.getCustomerCity() + " " + request.getCustomerPhoneNumber());
response.setStatus("SUCCESS");
return response;
}

}

For the purpose of this tutorial, I added very simple code to return a success response.

  • @Endpoint: This indicates that this class is a web service endpoint
  • @PayloadRoot: This indicates that incoming soap request for this method will have defined local part and namespace. It will basically try to match the RootElement of your xml message.
  • @ResponsePayload: This indicates that method will return a payload.

Configure Servlet Bean & WSDL Definition

  • Define the ServletRegistrationBean in configuration to register a servlet which will listen the incoming requests.
  • Define the configuration for WSDL Definition
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.tutorialflix.spring.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 WebServiceConfig extends WsConfigurerAdapter {

@Bean
public ServletRegistrationBean < MessageDispatcherServlet > messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean < > (servlet, "/ws/*");
}

@Bean(name = "customer")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("CustomerServicePort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://spring.tutorialflix.com/service/v1");
wsdl11Definition.setSchema(customerSchema());
return wsdl11Definition;
}

@Bean
public XsdSchema customerSchema() {
return new SimpleXsdSchema(new ClassPathResource("customer-service.xsd"));
}
}
  • portTypeName : Interface name

  • locationUri : URL to expose service

  • targetNamespace: Target name space for the WSDL elements

  • schema: Location of the schema

  • @Bean(name = “customer”) :Name of this bean will be used the wsdl name.

Configure Logging Interceptors

To log the payload of our SOAP messages we’ll add the below beans in the WebServiceConfig class.

1
2
3
4
5
6
7
8
9
10
11
@Bean
PayloadLoggingInterceptor payloadLoggingInterceptor() {
return new PayloadLoggingInterceptor();
}

@Bean
PayloadValidatingInterceptor payloadValidatingInterceptor() {
final PayloadValidatingInterceptor payloadValidatingInterceptor = new PayloadValidatingInterceptor();
payloadValidatingInterceptor.setSchema(new ClassPathResource("customer-service.xsd"));
return payloadValidatingInterceptor;
}

Configure Security Interceptors

XwsSecurityInterceptor will intercept the request and validate the username & password by the help of SimplePasswordValidationCallbackHandler.

For this post we are using username = admin and password = pwd123.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Bean
XwsSecurityInterceptor securityInterceptor() {
XwsSecurityInterceptor securityInterceptor = new XwsSecurityInterceptor();
securityInterceptor.setCallbackHandler(callbackHandler());
securityInterceptor.setPolicyConfiguration(new ClassPathResource("securityPolicy.xml"));
return securityInterceptor;
}

@Bean
SimplePasswordValidationCallbackHandler callbackHandler() {
SimplePasswordValidationCallbackHandler callbackHandler = new SimplePasswordValidationCallbackHandler();
callbackHandler.setUsersMap(Collections.singletonMap("admin", "pwd123"));
return callbackHandler;
}

Add interceptor to the chain

1
2
3
4
5
6
@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(payloadLoggingInterceptor());
interceptors.add(payloadValidatingInterceptor());
interceptors.add(securityInterceptor());
}

Adding the security policy

Now create a file with name securityPolicy.xml in the resources folder and add the below mentioned configuration.

1
2
3
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:RequireUsernameToken passwordDigestRequired="false" nonceRequired="false" />
</xwss:SecurityConfiguration>

Bootstrap as Spring Boot Application

Add following plugin in pom.xml to make the jar spring boot compatible.

1
2
3
4
5
6
7
8
9
10
11
12
 <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

Define the main method which will allow this application to run using Spring Boot.This class should be in the root package always for the component scan.

1
2
3
4
5
6
7
8
9
10
11
12
package com.tutorialflix.spring;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootSoapWebService {

public static void main(String[] args) {
SpringApplication.run(SpringBootSoapWebService.class, args);
}
}

Deploy the service

$ mvn spring-boot:run

Now, you can see the WSDL at the following location
http://localhost:8080/ws/customer.wsdl

Test the service

  • Import the wsdl in SOAP-UI & soap-ui will auto generate request structure for the request.

import-wsdl-in-soapui

  • Send request to service

run-request-in-soap-ui

Download the code

You can clone or download this project from Github

How to create SOAP webservice using Spring-WS & Spring Boot



Overview

In this tutorial, we’ll see how to create a SOAP webservice using Spring-WS and Spring Boot. This post will focus only on pure Java based approach using annotations.

Pre-requisties

  1. JDK 1.8 +
  2. Maven
  3. IDE

Approach

SOAP services can be developed with two methods

  1. Contract First : Define WSDL and Schema before writing any code.
  2. Contract Last: Auto-generate the WSDL and schemas from the java classes.

Spring-ws only supports the contract-first approach

Project setup

You can clone this project from Github to kick start the project

Create a maven project and add the following dependencies in the pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
</dependencies>

Schema Design

Contract first approach requires us to define the schema. And then we’ll use Spring-ws auto-generate WSDL out of the schema.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://spring.tutorialflix.com/types/v1"
xmlns:tns="http://spring.tutorialflix.com/types/v1" elementFormDefault="qualified">
<xs:element name="createCustomerRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="customerName">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
<xs:whiteSpace value="collapse" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="customerAge">
<xs:simpleType>
<xs:restriction base="xs:integer" />
</xs:simpleType>
</xs:element>
<xs:element name="customerCity">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
<xs:whiteSpace value="collapse" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="customerPhoneNumber">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
<xs:whiteSpace value="collapse" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="createCustomerResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="customerID" type="xs:integer" />
<xs:element name="details" type="xs:string" />
<xs:element name="status" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="createCustomerFault">
<xs:complexType>
<xs:sequence>
<xs:element name="errorMessage" type="xs:normalizedString" />
<xs:element name="errorCode" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Generate Java Classes

Now, we’ll jaxb2-maven-plugin to generate the java classes from the schema. Add the below plugin in your pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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>
  • schemaDirectory : location of the schema
  • outputDirectory: where we want our java classes.
  • clearOutputDir : making this true will delete the classes every time you compile the project

Now, we’ll generate the classes by issuing a following maven command.

$ mvn clean install

Now you can see the auto-generated classes in you project folder.

Setup Endpoint

Now, we’ll setup an endpoint in our Java code to serve the request. Create a class and annotate with @Endpoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.tutorialflix.spring.ws.endpoint;

import java.math.BigInteger;

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.tutorialflix.spring.types.v1.CreateCustomerRequest;
import com.tutorialflix.spring.types.v1.CreateCustomerResponse;

@Endpoint
public class CustomerServiceEndpoint {

@ResponsePayload
@PayloadRoot(localPart = "createCustomerRequest", namespace = "http://spring.tutorialflix.com/types/v1")
public CreateCustomerResponse createCustomer(@RequestPayload CreateCustomerRequest request) {

CreateCustomerResponse response = new CreateCustomerResponse();
response.setCustomerID(BigInteger.ONE);
response.setDetails(request.getCustomerName() + " " + request.getCustomerCity() + " " + request.getCustomerPhoneNumber());
response.setStatus("SUCCESS");
return response;
}

}

For the purpose of this tutorial, I added very simple code to return a success response.

  • @Endpoint: This indicates that this class is a web service endpoint
  • @PayloadRoot: This indicates that incoming soap request for this method will have defined local part and namespace. It will basically try to match the RootElement of your xml message.
  • @ResponsePayload: This indicates that method will return a payload.

Configure Servlet Bean & WSDL Definition

  • Define the ServletRegistrationBean in configuration to register a servlet which will listen the incoming requests.
  • Define the configuration for WSDL Definition
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.tutorialflix.spring.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 WebServiceConfig extends WsConfigurerAdapter {

@Bean
public ServletRegistrationBean < MessageDispatcherServlet > messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean < > (servlet, "/ws/*");
}

@Bean(name = "customer")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("CustomerServicePort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://spring.tutorialflix.com/service/v1");
wsdl11Definition.setSchema(customerSchema());
return wsdl11Definition;
}

@Bean
public XsdSchema customerSchema() {
return new SimpleXsdSchema(new ClassPathResource("customer-service.xsd"));
}
}
  • portTypeName : Interface name

  • locationUri : URL to expose service

  • targetNamespace: Target name space for the WSDL elements

  • schema: Location of the schema

  • @Bean(name = “customer”) :Name of this bean will be used the wsdl name.

Bootstrap as Spring Boot Application

Add following plugin in pom.xml to make the jar spring boot compatible.

1
2
3
4
5
6
7
8
9
10
11
12
 <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

Define the main method which will allow this application to run using Spring Boot.This class should be in the root package always for the component scan.

1
2
3
4
5
6
7
8
9
10
11
12
package com.tutorialflix.spring;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootSoapWebService {

public static void main(String[] args) {
SpringApplication.run(SpringBootSoapWebService.class, args);
}
}

Deploy the service

$ mvn spring-boot:run

Now, you can see the WSDL at the following location
http://localhost:8080/ws/customer.wsdl

Test the service

  • Import the wsdl in SOAP-UI & soap-ui will auto generate request structure for the request.

import-wsdl-in-soapui

  • Send request to service

run-request-in-soap-ui

Download the code

You can clone or download this project from Github

How to create a maven project



Steps

Open Eclipse

Click File / New / Maven Project

new-maven-project

Mark Create a Simple project option

create-simple-maven-project

Enter the group id, artifact, version and press the Finish .

artifact-details

Project Structure will be like below image.

project-structure

Video Tutorial

Developing REST Service using Spring Boot



Overview

The tutorial will show, how to develop a REST API with Spring. We’ll look into the Spring Boot solution for creating the application.

We’ll primarily use Java configuration in this tutorial.

Pre-requisties

  • JDK 1.8
  • Maven
  • IDE (for ease of use)

Setup maven project

Creat a maven project and add the required dependencies and plugins in pom.xml

We will use the dependencyManagement to define a standard version of an artifact to use across multiple projects.

We will allow spring-boot-starter-parent to manage the version of the artifacts.

1
2
3
4
5
6
7
8
9
10
11
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Now we’ll add the spring-boot-starter-web dependency.

Spring Boot Starter Web includes:

  • spring-web module
  • spring-webmvc module
  • tomcat starter

Spring-web & Spring-webmvc are required for spring appplication while tomcat starter is required to run web application directly without explicitly installing any server.

1
2
3
4
5
6
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

Spring Boot Maven Plugin provides Spring Boot support in Maven, letting you package executable jar or war archives and run an application “in-place”.

1
2
3
4
5
6
7
8
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

Creating a Spring Boot Application

Create a class with main method. Annotate the class with @SpringBootApplication. Call the run method of SpringApplication class

1
2
3
4
5
6
7
8
9
10
11
12
package com.tutorialflix.spring.web;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootWebApplication {

public static void main(String[] args) {
SpringApplication.run(SpringBootWebApplication.class, args);
}
}

@SpringBootApplication includes the functionality of following annotations:

  • @Configuration
  • @EnableAutoConfiguration
  • @ComponentScan.

By default, it will perform the component scan in base package. So make sure SpringBootWebApplication class is present in the base package.

Creating a REST Controller

Create a class with a meaningful name based on your requirement & annotate the class with @RestController. The @RestController is the central artifact in the entire Web Tier of the RESTful API.

1
2
3
4
5
6
7
8
9
package com.tutorialflix.spring.web.contrroller;

import org.springframework.stereotype.RestController;

@RestController
public class MyRestController {


}

Create a GET method to accept requests

Create a method named home to accept the request on ‘/‘ url and show the index.html

1
2
3
4
5
6

@GetMapping("/sayHello")
public Map<String,String> sayHello() {
Map map = new HashMap<>();
map.put("response","Hello, how are you");
return map;

Create a POST method to accept requests

Create a method named home to accept the request on ‘/‘ url and show the index.html

1
2
3
4
5
6
@PostMapping("/sayHelloWithName")
public Map<String,String> sayHelloWithName(Map<String,String> request) {
Map map = new HashMap<>();
map.put("response","Hello, how are you " + request.get("name"));
return map;
}

Configuration using properties file

Create a file application.properties inside resources folder of application and following properties.

1
2
server.port=8081
logging.level.org.springframework.web=DEBUG

server.port : to change the default port 8080 to any other port number.

logging.level.org.springframework.web : to change the log level default INFO to DEBUG

Run the REST API

1
$ mvn spring-boot:run

Test

Goto http://localhost:8081/

Developing SOAP Web service using Apache CXF and Apache Camel



Overview

In this post, we will walk through the steps to develop a SOAP service using Java and we will also leverage Spring , Apache Camel & Apache CXF.

Pre-requisties

1) JDK 1.8 for code development
2) Maven for dependency management
3) JBoss Fuse 6.3 for deployment

Code Development

Maven Project with required dependencies

Create a maven project using IDE and add following dependencies in the pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<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.customer.service</groupId>
<artifactId>customer-service-impl</artifactId>
<version>1.0.0</version>
<packaging>bundle</packaging>
<name>Customer Service</name>

<properties>
<camel.version>2.17.0</camel.version>
</properties>
<dependencies>
<!-- Camel Dependency -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-sql</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- For compliation of java code , you can specify the java version also -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<!-- For creating packing as bundle i.e. jar to bundle -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<version>2.4.0</version>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.7.8</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${basedir}/src/main/java</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/wsdl/customer-service.wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

About the components used in pom.xml

Project structure
project-folder-structure

WSDL & Schema

Designing Schema

You can refer this post for detail discussion on designing schema

Below is the schema which we will use in this example
src/main/resources/wsdl/customer-service.wsdl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://service.customer.com/types/v1"
xmlns:tns="http://service.customer.com/types/v1" elementFormDefault="qualified">
<xs:element name="createCustomerRequest" type="tns:CreateCustomerRequest" />
<xs:element name="createCustomerResponse" type="tns:CreateCustomerResponse" />
<xs:element name="createCustomerFault" type="tns:CreateCustomerFault" />
<xs:complexType name="CreateCustomerRequest">
<xs:sequence>
<xs:element name="customerName">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
<xs:whiteSpace value="collapse" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="customerAge">
<xs:simpleType>
<xs:restriction base="xs:integer" />
</xs:simpleType>
</xs:element>
<xs:element name="customerCity">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
<xs:whiteSpace value="collapse" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="customerPhoneNumber">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
<xs:whiteSpace value="collapse" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CreateCustomerResponse">
<xs:sequence>
<xs:element name="customerID" type="xs:integer" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="CreateCustomerFault">
<xs:sequence>
<xs:element name="errorMessage" type="xs:normalizedString" />
<xs:element name="errorCode" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:schema>

Designing WSDL

You can refer this post for detail discussion on designing wsdl.

Below is the WSDL which we will use in this example
src/main/resources/wsdl/customer-service.xsd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:cs="http://service.customer.com/types/v1"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://service.customer.com/v1"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="customer-service" targetNamespace="http://service.customer.com/v1">
<wsdl:types>
<xsd:schema>
<xsd:import namespace="http://service.customer.com/types/v1" schemaLocation="schemas/customer-service.xsd" />
</xsd:schema>
</wsdl:types>
<wsdl:message name="createCustomerRequest">
<wsdl:part name="createCustomerRequest" element="cs:createCustomerRequest" />
</wsdl:message>
<wsdl:message name="createCustomerResponse">
<wsdl:part name="createCustomerResponse" element="cs:createCustomerResponse" />
</wsdl:message>
<wsdl:message name="createCustomerFault">
<wsdl:part name="createCustomerFault" element="cs:createCustomerFault" />
</wsdl:message>
<wsdl:portType name="CustomerServicePort">
<wsdl:operation name="createCustomer">
<wsdl:input message="tns:createCustomerRequest" name="createCustomerRequest" />
<wsdl:output message="tns:createCustomerResponse" name="createCustomerResponse" />
<wsdl:fault message="tns:createCustomerFault" name="createCustomerFault" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CustomerServiceBinding" type="tns:CustomerServicePort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="createCustomer">
<soap:operation soapAction="createCustomer" style="document" />
<wsdl:input name="createCustomerRequest">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="createCustomerResponse">
<soap:body use="literal" />
</wsdl:output>
<wsdl:fault name="createCustomerFault">
<soap:fault name="createCustomerFault" use="literal" />
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="CustomerService">
<wsdl:port name="CustomerServicePort" binding="tns:CustomerServiceBinding">
<soap:address location="http://0.0.0.0:8181/cxf/customerservice/v1" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

XML Based Spring configuration

We’ll use the xml based spring configuration for this example to expose the service.

Define the CXF Endpoint

Now, we’ll define the CXF Endpoint to expose the service

  • address specify the path where you want to expose your service
  • serviceName & endpointName should be same as specified in wsdl,
  • wsdlURL relative to resources folder or it can a http url also.
1
2
3
<cxf:cxfEndpoint name="customerServiceCXF" address="/customerservice" 
endpointName="cs:CustomerServicePort" serviceName="cs:CustomerService"
xmlns:cs="http://service.customer.com/v1" wsdlURL="wsdl/customer-service.wsdl"/>
Define the CamelContext

All the camel routes will be written in the camel context, so we will create a camelContext in the same file.

1
2
3
<camel:camelContext>
<-- Camel routes here -->
</camel:camelContext>

Define the dataFormats

We will define the data format to convert the soap xml payload into java object and vice versa. Context path is the root folder where you have all the auto-generated classes (WSDL & schema objects created using codegen-plugin)

1
2
3
<camel:dataFormats>
<camel:jaxb id="customerJaxb" contextPath="com.customer.service.types.v1"/>
</camel:dataFormats>
Define the camel route

We’ll define the camel route based on the logic, in this example route is pretty small & simple, but trust me at enterprise level it can be bit complex and longer.

1
2
3
4
5
6
<camel:route id="customer-service-main-route">
<camel:from uri="cxf:bean:customerServiceCXF?dataFormat=PAYLOAD"/>
<camel:unmarshal ref="customerJaxb"/>
<camel:process ref="customerResponseProcessor"></camel:process>
<camel:marshal ref="customerJaxb"/>
</camel:route>

  • cxf component & bean id is used to lookup the cxfEndpoint.
  • camel:from will allow to consume the request(s) incoming the cxf endpoint.
  • camel:unmarshal is used for converting soap payload to java objects
  • camel:process is used for the logic to be performed in the service
  • camel:marshal is used for converting java object to soap xml.

This is how your routes file will look like
src/main/resources/META-INF/spring/bundle-context-routes.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:cxf="http://camel.apache.org/schema/cxf" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd">
<cxf:cxfEndpoint name="customerServiceCXF" address="/customerservice" endpointName="cs:CustomerServicePort"
xmlns:cs="http://service.customer.com/v1" serviceName="cs:CustomerService" wsdlURL="wsdl/customer-service.wsdl" />
<camel:camelContext>
<camel:dataFormats>
<camel:jaxb id="customerJaxb" contextPath="com.customer.service.types.v1"/>
</camel:dataFormats>
<camel:route id="customer-service-main-route">
<camel:from uri="cxf:bean:customerServiceCXF?dataFormat=PAYLOAD"/>
<camel:unmarshal ref="customerJaxb"/>
<camel:process ref="customerResponseProcessor"></camel:process>
</camel:route>
</camel:camelContext>
<bean id="customerResponseProcessor" class="com.customer.service.processor.CustomerResponseProcessor"/>
</beans>

Response Processor

For this example, we will write a processor which stores the employee data in map and return customer ID.

Create CustomerResponseProcessor.java in src/main/resources

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.customer.service.processor;

import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.customer.service.types.v1.CreateCustomerRequest;
import com.customer.service.types.v1.CreateCustomerResponse;

public class CustomerRequestProcessor implements Processor {

private static final Logger LOGGER = LoggerFactory.getLogger(CustomerRequestProcessor.class);
private static long counter = 1;
private static Map < Long, CreateCustomerRequest > customers = new HashMap();

@Override
public void process(Exchange exchange) throws Exception {
CreateCustomerRequest request = exchange.getIn().getBody(CreateCustomerRequest.class);
customers.put(counter, request);
synchronized(this) {
counter++;
}

CreateCustomerResponse response = new CreateCustomerResponse();
response.setCustomerID(BigInteger.valueOf(counter));

LOGGER.debug("Employee stored in map ID: " + counter);

exchange.getOut().setBody(response);
}

}

Code Build

Now we’ll compile the code & package it as .jar using maven.

1
$ mvn clean install

Deploy on JBoss Fuse

Once we have the jar file ready with us, we’ll deploy it JBoss Fuse 6.3. You can refer this post to learn more about the deployments on JBoss Fuse.

1
2
$ cd fuse/bin
$ ./fuse

jboss-fuse-welcome
Run following command for the deployment

JBossFuse:admin@root> install -s mvn:com.customer.service/customer-service-impl/1.0.0

Now you can check the service url by visiting below url
http://localhost:8181/cxf

How to load property file in java



Overview

Application mostly require a file to store the configuration or data oustide the complied code. Most commonly used method is to store in properties file in the form of key value pair. In the below example. we’ll see how to read those properties file using Java.

Java has in-built support in java.util.Properties class to perform read/write operations on the properties file.

Properties file

config.properties

1
2
name=tutorialflix
description=loading properties from file

Reading properties file from classpath or resources folder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.tutorialflix.example.properties.file;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class LoadPropertyFileFromClasspath {

public static void main(String[] args) {

try (InputStream input = LoadPropertyFileExample.class.getClassLoader().getResourceAsStream("config.properties")) {

Properties prop = new Properties();

// load a properties file
prop.load(input);

// get the property value and print it out
System.out.println(prop.getProperty("name"));
System.out.println(prop.getProperty("description"));

} catch (IOException ex) {
ex.printStackTrace();
}

}

}

Reading properties file from disk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.tutorialflix.example.properties.file;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class LoadPropertyFileFromPath {

public static void main(String[] args) {

try (InputStream input = new FileInputStream("path/to/config.properties")) {


Properties prop = new Properties();

// load a properties file
prop.load(input);

// get the property value and print it out
System.out.println(prop.getProperty("name"));
System.out.println(prop.getProperty("description"));

} catch (IOException ex) {
ex.printStackTrace();
}

}

}

How to create a WSDL file



Introduction

WSDL stands for Web Services Description Language. WSDL is used to describe web services and also known as Contract. It is the base building block to create a SOAP webservice in Contract-First Approach.

Creation of WSDL consist of following:

  • Schema Design
  • WSDL Design

In the below example, we are creating a WSDL which contain a single operation createCustomer. You can follow the similar approach to add more operation in the WSDL.

Schema Design

First of all, we will create a schema file to define the request, response and fault structure.

XML Definition

Create a file of .xsd extension, in this case we are using customer-service.xsd

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://service.customer.com/types/v1"
xmlns:tns="http://service.customer.com/types/v1" elementFormDefault="qualified">

<!-- Schema Content here -->

</xs:schema>

Request structure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<xs:element name="createCustomerRequest" type="tns:CreateCustomerRequest" />
<xs:complexType name="CreateCustomerRequest">
<xs:sequence>
<xs:element name="customerName" type="xs:normalizedString"/>
<xs:element name="customerAge" type="xs:int" />
<xs:element name="customerPhoneNumber">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
<xs:whiteSpace value="collapse" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>

Response structure

1
2
3
4
5
6
<xs:element name="createCustomerResponse" type="tns:CreateCustomerResponse" />
<xs:complexType name="CreateCustomerResponse">
<xs:sequence>
<xs:element name="customerID" type="xs:integer" />
</xs:sequence>
</xs:complexType>

Fault structure

1
2
3
4
5
6
7
<xs:element name="createCustomerFault" type="tns:CreateCustomerFault" />
<xs:complexType name="CreateCustomerFault">
<xs:sequence>
<xs:element name="errorMessage" type="xs:normalizedString" />
<xs:element name="errorCode" type="xs:int" />
</xs:sequence>
</xs:complexType>

WSDL Design

Definitions

Create a file of .wsdl extension, in this case we are using customer-service.wsdl

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="customer-service"
xmlns:tns="http://service.customer.com/v1"
xmlns:cs="http://service.customer.com/types/v1" targetNamespace="http://service.customer.com/v1">

</wsdl:definitions>

Schema Import

Import the schema which we have created in above example.

1
2
3
4
5
<wsdl:types>
<xsd:schema>
<xsd:import namespace="http://service.customer.com/types/v1" schemaLocation="schemas/customer-service.xsd"/>
</xsd:schema>
</wsdl:types>

Messages

Defines the data elements for each operation

1
2
3
4
5
6
7
8
9
<wsdl:message name="createCustomerRequest">
<wsdl:part name="createCustomerRequest" element="cs:createCustomerRequest"></wsdl:part>
</wsdl:message>
<wsdl:message name="createCustomerResponse">
<wsdl:part name="createCustomerResponse" element="cs:createCustomerResponse"></wsdl:part>
</wsdl:message>
<wsdl:message name="createCustomerFault">
<wsdl:part name="createCustomerFault" element="cs:createCustomerFault"></wsdl:part>
</wsdl:message>

PortType

Describes the operations that can be performed and the messages involved.

1
2
3
4
5
6
7
<wsdl:portType name="CustomerServicePort">
<wsdl:operation name="createCustomer">
<wsdl:input message="tns:createCustomerRequest" name="createCustomerRequest" />
<wsdl:output message="tns:createCustomerResponse" name="createCustomerResponse" />
<wsdl:fault message="tns:createCustomerFault" name="createCustomerFault"></wsdl:fault>
</wsdl:operation>
</wsdl:portType>

Binding

Defines the protocol and data format for each port type

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<wsdl:binding name="CustomerServiceBinding" type="tns:CustomerServicePort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="createCustomer">
<soap:operation soapAction="createCustomer" style="document" />
<wsdl:input name="createCustomerRequest">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="createCustomerResponse">
<soap:body use="literal" />
</wsdl:output>
<wsdl:fault name="createCustomerFault">
<soap:fault name="createCustomerFault" use="literal" />
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>

  • binding element has two attributes - name and type. The name attribute (you can use any name you want) defines the name of the binding, and the type attribute points to the port for the binding, in this case the “CustomerServicePort” port.

  • soap:binding element has two attributes - style and transport. The style attribute can be “rpc” or “document”. In this case we use document. The transport attribute defines the SOAP protocol to use. In this case we use HTTP.

  • operation element defines each operation that the portType exposes. For each operation the corresponding SOAP action has to be defined. You must also specify how the input and output are encoded. In this case we use “literal”.

Service

Defines the port and binding with the address where you want to expose your service.

<wsdl:service name="CustomerService">
    <wsdl:port name="CustomerServicePort" binding="tns:CustomerServiceBinding">
        <soap:address location="http://0.0.0.0:8181/cxf/customerservice/v1"/>
    </wsdl:port>
</wsdl:service>

You can download the WSDL and XSD file for your reference

SOAP - Simple Object Access Protocol



What is SOAP ?

Simple Object Access Protocol is a messaging protocol specification for exchanging structured information. Its purpose is to provide extensibility, neutrality and independence.

  • SOAP uses XML for its message format.
  • SOAP relies on application layer protocols such as HTTP, SMTP, TCP, UDP, or JMS for message negotiation and transmission.

SOAP consists of three parts

  • an envelope, which defines the message structure and how to process it
  • a set of encoding rules for expressing instances of application-defined datatypes
  • a convention for representing procedure calls and responses

SOAP building blocks

A SOAP message is an ordinary XML document containing the following elements:

Element Description Required
Envelope Identifies the XML document as a SOAP message Yes
Header Contains header information No
Body Contains call, and response information Yes
Fault Provides information about errors that occurred while processing the message No

Request Format

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://service.customer.com/types/v1">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-F434D320D890F7CF1715251639631263">
<wsse:Username>admin</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">admin</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<v1:deleteCustomerRequest>
<v1:customerID>123321</v1:customerID>
</v1:deleteCustomerRequest>
</soapenv:Body>
</soapenv:Envelope>

Response Format

1
2
3
4
5
6
7
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://service.customer.com/types/v1">
<soapenv:Body>
<v1:deleteCustomerResponse>
<v1:message>Customer Deleted Successfully</v1:message>
</v1:deleteCustomerResponse>
</soapenv:Body>
</soapenv:Envelope>

Fault Format

1
2
3
4
5
6
7
8
9
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd=="http://www.w3.org/1999/XMLSchema">
<soapenv:Body>
<soapenv:Fault>
<faultcode xsi:type="xsd:string">SOAP_FAULT_DELETECUSTOMER</faultcode>
<faultstring xsi:type="xsd:string">Customer not present</faultstring>
<faultactor>CustNotFound</faultactor>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×