Spring Boot Security MySQL Database Integration Example

PROGRAMMINGJava ExamplesC Examples
Java Examples
C Examples
C Tutorials
aws
JAVAEXCEPTIONSCOLLECTIONSSWINGJDBC
EXCEPTIONS
COLLECTIONS
SWING
JDBC
JAVA 8
SPRING
SPRING BOOT
HIBERNATE
PYTHON
PHP
JQUERY
PROGRAMMINGJava ExamplesC Examples
Java Examples
C Examples
C Tutorials
aws
In this tutorial, we are going to show how to secure spring boot rest services with MySQL database integration.
In the previous example, we have discussed spring boot in-memory security where the user validation happened at in-memory, as part of this Spring Boot Security MySQL Database Integration the user validation takes place in the MySQL database.
Spring Boot 2.0.6
Spring Boot WEB
Spring Security 2.0.6
Spring Boot Data JPA
MySQL 5.1.47
Java 8
As part of this example, I am going to create a simple spring boot rest service which provides two different rest endpoints, one is – to say hello to you and another one is secured rest endpoint which provides all item details.
Here we need 3 different tables such as USER, ROLE and USER_ROLE. The relationship between USER and ROLE is many to many because one USER can have multiple ROLES and one ROLE can be assigned to multiple USERS.
USER:
CREATE TABLE `user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `active` int(11) DEFAULT NULL,
  `lastname` varchar(255) NOT NULL,
  `firstname` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
ROLE:
CREATE TABLE `role` (
  `role_id` int(11) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
USER_ROLE:
As per the normalization we need to have this intermediate table to represent the many to many relationships.
CREATE TABLE `user_role` (
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  PRIMARY KEY (`user_id`,`role_id`),
  UNIQUE KEY `UK_it77eq964jhfqtu54081ebtio` (`role_id`),
  CONSTRAINT `FK859n2jvi8ivhui0rl0esws6o` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`),
  CONSTRAINT `FKa68196081fvovjhkek5m97n3y` FOREIGN KEY (`role_id`) REFERENCES `role` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Insert Data:
-- creating user
insert into OTP.USER values(1,1,'shekhar','chandra','12345');
-- creating ADMIN role
insert into OTP.ROLE values(1,'ADMIN');
-- Mapping ADMIN role id (1) to shekhar user userid (1)
insert into OTP.USER_ROLE values(1,1);
<?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.onlinetutorialspoint</groupId>
  <artifactId>SpringBoot-Security-Mysql-Example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>SpringBoot-Security-Mysql-Example</name>
  <description>Spring Boot Security MySQL Database Integration Example</description>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.6.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>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

Database configuration properties.
server.port=8080
spring.datasource.driver-class-name: com.mysql.jdbc.Driver
spring.datasource.url: jdbc:mysql://localhost:3306/otp
spring.datasource.username: root
spring.datasource.password: 12345

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
Item Model: Carrying Items.
package com.onlinetutorialspoint.model;

import java.io.Serializable;

public class Item implements Serializable {
    private Integer id;
    private String name;
    private String category;

    public Item() {
    }

    public Item(Integer id, String name, String category) {
        this.id = id;
        this.name = name;
        this.category = category;
    }
    // Getters and Setters
}

Creating JPA Entities:
User.java representing USER table.
package com.onlinetutorialspoint.model;

import javax.persistence.*;
import java.util.Set;

@Entity
@Table(name="user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="user_id")
    private int id;

    @Column(name="firstname")
        private String firstName;

    @Column(name="lastname")
    private String lastName;

    private String password;
    @Column(name="active")
    private int isActive;

    @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    @JoinTable(name="user_role",joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set roles;

    public User() {
    }

    public User(User user) {
        this.id = user.getId();
        this.firstName = user.getFirstName();
        this.lastName = user.getLastName();
        this.password = user.getPassword();
        this.isActive = user.getIsActive();
        this.roles = user.getRoles();
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getIsActive() {
        return isActive;
    }

    public void setIsActive(int isActive) {
        this.isActive = isActive;
    }

    public Set getRoles() {
        return roles;
    }

    public void setRoles(Set roles) {
        this.roles = roles;
    }

Role.java representing ROLE table.
package com.onlinetutorialspoint.model;

import javax.persistence.*;

@Entity
@Table(name="role")
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "role_id")
    private int id;

    @Column(name = "role_name")
    private String roleName;

    public Role() {
    }

    public Role(int id, String roleName) {
        this.id = id;
        this.roleName = roleName;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
}

Creating JPA Repository.
package com.onlinetutorialspoint.repos;

import com.onlinetutorialspoint.model.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UsersRepository extends JpaRepository<User, Integer> {
    Optional<User> findByFirstName(String firstname);
}

Spring Security UserdetailService Implementation.
package com.onlinetutorialspoint.service;

import com.onlinetutorialspoint.model.User;
import com.onlinetutorialspoint.model.UserDetailsImpl;
import com.onlinetutorialspoint.repos.UsersRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UsersRepository usersRepository;
    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        Optional<User> optionalUser = usersRepository.findByFirstName(userName);
        return Optional.ofNullable(optionalUser).orElseThrow(()->new UsernameNotFoundException("Username Not Found"))
               .map(UserDetailsImpl::new).get();
    }
}

Spring Security UserDetails implementation.
package com.onlinetutorialspoint.model;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;
import java.util.stream.Collectors;

public class UserDetailsImpl extends User implements UserDetails {

    public UserDetailsImpl(User user) {
        super(user);
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return getRoles()
                .stream()
                .map(role-> new SimpleGrantedAuthority("ROLE_"+role.getRoleName()))
                .collect(Collectors.toList());
    }

    @Override
    public String getPassword() {
        return super.getPassword();
    }

    @Override
    public String getUsername() {
        return super.getFirstName();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

Spring Security Configuration
package com.onlinetutorialspoint.configuration;

import com.onlinetutorialspoint.repos.UsersRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
@EnableWebSecurity
@EnableJpaRepositories(basePackageClasses = UsersRepository.class)
public class SecureConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailsService;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(getPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable();
        http.authorizeRequests()
                .antMatchers("**/getAllItems").authenticated()
                .anyRequest().permitAll()
                .and().formLogin().permitAll();
    }

    private PasswordEncoder getPasswordEncoder() {
        return new PasswordEncoder() {
            @Override
            public String encode(CharSequence charSequence) {
                return charSequence.toString();
            }

            @Override
            public boolean matches(CharSequence charSequence, String s) {
                return true;
            }
        };
    }
}

Creating the Rest Controller to provide /hello and /getAllItems rest endpoints.
package com.onlinetutorialspoint.controller;

import com.onlinetutorialspoint.model.Item;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;

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

@RestController
public class ItemController {

    @Autowired
    ItemController itemService;

    public static List<Item> items;
    static{
        items = new ArrayList<>(Arrays.asList(new Item(1,"Spring Boot in Action","Books"),
                new Item(2,"Java 8 in Action","Books"),
                new Item(3,"Data Structures","Books"),
                new Item(4,"Spring Boot Security","Books")));
    }

    @PreAuthorize("hasAnyRole('ADMIN')")
    @RequestMapping("/getAllItems")
    @ResponseBody
    public ResponseEntity<List<Item>> getAllItems() {
        //Reading all items (ADMIN only can access this)
        List<Item> items = this.items;
        System.out.println("Reading items: "+items);
        return new ResponseEntity<List<Item>>(items, HttpStatus.OK);
    }

    @RequestMapping("/hello")
    public String sayHello(){
        return "Hello User!";
    }

}

Main class.

package com.onlinetutorialspoint;

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

@SpringBootApplication
public class SpringBootSecurityMysqlExampleApplication {

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

mvn spring-boot:run

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.6.RELEASE)

2018-10-28 12:52:26.892  INFO 13656 --- [           main] pringBootSecurityMysqlExampleApplication : Starting SpringBootSecurityMysqlExampleApplication on DESKTOP-RN4SMHT with PID 13656 (E:\work\SpringBoot-Security-Mysql-Example\target\classes started by Lenovo in E:\work\SpringBoot-Security-Mysql-Example)
2018-10-28 12:52:26.911  INFO 13656 --- [           main] pringBootSecurityMysqlExampleApplication : No active profile set, falling back to default profiles: default
2018-10-28 12:52:27.142  INFO 13656 --- [           main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@14dd7b39: startup date [Sun Oct 28 12:52:27 IST 2018]; root of context hierarchy
.....
.....
Accessing /hello (unsecured) endpoint
Accessing /getAllItems secured endpoint — An ADMIN can access this endpoint with valid user credentials.
As soon as we access the localhost:8080/getAllItems endpoint, the spring automatically redirects our request to the login page as it is a secured service. Here we have to provide our valid user credentials then only it will allow us to access the /getAllItems endpoint.
Note: We haven’t created this login form at all. Spring has given us to provide the login details.
Let’s provide invalid user credentials and see what will happen.
Here I provided invalid username like shekhar123 and click on Login button, as a result, we should get the below error response saying login attempt was not successful.
Let’s provide valid user credentials and see the result.
Now we can able to see all items provided by rest endpoint.
Spring Security Docs
Spring Boot JPA MySql Integration
Hibernate Many to Many Relationship 
Happy Learning 🙂


SpringBoot-Security-Mysql-Example

File size: 108 KB
Downloads: 2086


Spring Boot Environment Properties reading based on activeprofile
Spring Boot In Memory Basic Authentication Security
How to change Spring Boot Tomcat Port Number
How To Change Spring Boot Context Path
Spring Boot How to change the Tomcat to Jetty Server
Spring Boot JPA Integration Example
Spring Boot JdbcTemplate CRUD Operations Mysql
Spring Boot Hibernate Integration Example
Spring Boot PDF iText integration with String Template
Spring Boot Batch Example Csv to Database
Spring Boot H2 Database + JDBC Template Example
Spring Boot Actuator Database Health Check
How to connect MySQL Database in Eclipse
Spring Boot Multiple Data Sources Example
Spring Boot Basic Authentication Example

Spring Boot Environment Properties reading based on activeprofile
Spring Boot In Memory Basic Authentication Security
How to change Spring Boot Tomcat Port Number
How To Change Spring Boot Context Path
Spring Boot How to change the Tomcat to Jetty Server
Spring Boot JPA Integration Example
Spring Boot JdbcTemplate CRUD Operations Mysql
Spring Boot Hibernate Integration Example
Spring Boot PDF iText integration with String Template
Spring Boot Batch Example Csv to Database
Spring Boot H2 Database + JDBC Template Example
Spring Boot Actuator Database Health Check
How to connect MySQL Database in Eclipse
Spring Boot Multiple Data Sources Example
Spring Boot Basic Authentication Example






W. Wallace
January 15, 2019 at 10:25 am - Reply 

nice one. One question how can i make it  “@PreAuthorize(“hasAnyRole(‘ADMIN’)”) ” generic ? @PreAuthorize(“hasAnyRole(‘< LIST OF GROUPS FROM DATABASE')")









chandrashekhar
January 15, 2019 at 11:26 am - Reply 

You can define the SQL query logic like the following..
@Component("app_roles")
public class Roles{
@Value("${role.roleNames}")
private String[] roles;
public String[] getRoles() {
// SQL goes here..
//this.roles = results;
return this.roles;
}
}
call the getRoles() method as below.
@PreAuthorize("hasAnyRole(@app_roles.getRoles())")
public ResponseEntity> getAllItems() {}
It may help you.
Thanks,
Chandra Shekhar G











himanshu
June 27, 2019 at 1:20 am - Reply 

this is the least complex example of such type i could find. Thanks.
I couldn’t understand the hashes you provided in the sql queries `UK_it77eq964jhfqtu54081ebtio` , can you please explain or point to right resource.









himanshu
June 27, 2019 at 1:37 am - Reply 

also how did you integrate or create login page? or does it come automatically when you chose formlogin in secureconfig









Abdullah-Al Tareq
August 10, 2019 at 4:02 pm - Reply 

Please fix the User.java file.









chandrashekhar
August 14, 2019 at 5:24 pm - Reply 

Thanks Abdullah, updated the source..
Cheers!
Chandra Shekhar G











John
September 18, 2019 at 8:25 pm - Reply 

Getting error:
Your login attempt was not successful, try again.
Reason: No value present









Ramees
June 12, 2020 at 12:28 pm - Reply 

Password is not checking










W. Wallace
January 15, 2019 at 10:25 am - Reply 

nice one. One question how can i make it  “@PreAuthorize(“hasAnyRole(‘ADMIN’)”) ” generic ? @PreAuthorize(“hasAnyRole(‘< LIST OF GROUPS FROM DATABASE')")









chandrashekhar
January 15, 2019 at 11:26 am - Reply 

You can define the SQL query logic like the following..
@Component("app_roles")
public class Roles{
@Value("${role.roleNames}")
private String[] roles;
public String[] getRoles() {
// SQL goes here..
//this.roles = results;
return this.roles;
}
}
call the getRoles() method as below.
@PreAuthorize("hasAnyRole(@app_roles.getRoles())")
public ResponseEntity> getAllItems() {}
It may help you.
Thanks,
Chandra Shekhar G






nice one. One question how can i make it  “@PreAuthorize(“hasAnyRole(‘ADMIN’)”) ” generic ? @PreAuthorize(“hasAnyRole(‘< LIST OF GROUPS FROM DATABASE')")





chandrashekhar
January 15, 2019 at 11:26 am - Reply 

You can define the SQL query logic like the following..
@Component("app_roles")
public class Roles{
@Value("${role.roleNames}")
private String[] roles;
public String[] getRoles() {
// SQL goes here..
//this.roles = results;
return this.roles;
}
}
call the getRoles() method as below.
@PreAuthorize("hasAnyRole(@app_roles.getRoles())")
public ResponseEntity> getAllItems() {}
It may help you.
Thanks,
Chandra Shekhar G




You can define the SQL query logic like the following..
@Component("app_roles")
public class Roles{
@Value("${role.roleNames}")
private String[] roles;
public String[] getRoles() {
// SQL goes here..
//this.roles = results;
return this.roles;
}
}
call the getRoles() method as below.
@PreAuthorize("hasAnyRole(@app_roles.getRoles())")
public ResponseEntity> getAllItems() {}
It may help you.
Thanks,
Chandra Shekhar G





himanshu
June 27, 2019 at 1:20 am - Reply 

this is the least complex example of such type i could find. Thanks.
I couldn’t understand the hashes you provided in the sql queries `UK_it77eq964jhfqtu54081ebtio` , can you please explain or point to right resource.




this is the least complex example of such type i could find. Thanks.
I couldn’t understand the hashes you provided in the sql queries `UK_it77eq964jhfqtu54081ebtio` , can you please explain or point to right resource.





himanshu
June 27, 2019 at 1:37 am - Reply 

also how did you integrate or create login page? or does it come automatically when you chose formlogin in secureconfig




also how did you integrate or create login page? or does it come automatically when you chose formlogin in secureconfig





Abdullah-Al Tareq
August 10, 2019 at 4:02 pm - Reply 

Please fix the User.java file.









chandrashekhar
August 14, 2019 at 5:24 pm - Reply 

Thanks Abdullah, updated the source..
Cheers!
Chandra Shekhar G






Please fix the User.java file.





chandrashekhar
August 14, 2019 at 5:24 pm - Reply 

Thanks Abdullah, updated the source..
Cheers!
Chandra Shekhar G




Thanks Abdullah, updated the source..
Cheers!
Chandra Shekhar G





John
September 18, 2019 at 8:25 pm - Reply 

Getting error:
Your login attempt was not successful, try again.
Reason: No value present




Getting error:
Your login attempt was not successful, try again.
Reason: No value present





Ramees
June 12, 2020 at 12:28 pm - Reply 

Password is not checking




Password is not checking
 


Δ
 Spring Boot – Hello World
 Spring Boot – MVC Example
 Spring Boot- Change Context Path
 Spring Boot – Change Tomcat Port Number
 Spring Boot – Change Tomcat to Jetty Server
 Spring Boot – Tomcat session timeout
 Spring Boot – Enable Random Port
 Spring Boot – Properties File
 Spring Boot – Beans Lazy Loading
 Spring Boot – Set Favicon image
 Spring Boot – Set Custom Banner
 Spring Boot – Set Application TimeZone
 Spring Boot – Send Mail
 Spring Boot – FileUpload Ajax
 Spring Boot – Actuator
 Spring Boot – Actuator Database Health Check
 Spring Boot – Swagger
 Spring Boot – Enable CORS
 Spring Boot – External Apache ActiveMQ Setup
 Spring Boot – Inmemory Apache ActiveMq
 Spring Boot – Scheduler Job
 Spring Boot – Exception Handling
 Spring Boot – Hibernate CRUD
 Spring Boot – JPA Integration CRUD
 Spring Boot – JPA DataRest CRUD
 Spring Boot – JdbcTemplate CRUD
 Spring Boot – Multiple Data Sources Config
 Spring Boot – JNDI Configuration
 Spring Boot – H2 Database CRUD
 Spring Boot – MongoDB CRUD
 Spring Boot – Redis Data CRUD
 Spring Boot – MVC Login Form Validation
 Spring Boot – Custom Error Pages
 Spring Boot – iText PDF
 Spring Boot – Enable SSL (HTTPs)
 Spring Boot – Basic Authentication
 Spring Boot – In Memory Basic Authentication
 Spring Boot – Security MySQL Database Integration
 Spring Boot – Redis Cache – Redis Server
 Spring Boot – Hazelcast Cache
 Spring Boot – EhCache
 Spring Boot – Kafka Producer
 Spring Boot – Kafka Consumer
 Spring Boot – Kafka JSON Message to Kafka Topic
 Spring Boot – RabbitMQ Publisher
 Spring Boot – RabbitMQ Consumer
 Spring Boot – SOAP Consumer
 Spring Boot – Soap WebServices
 Spring Boot – Batch Csv to Database
 Spring Boot – Eureka Server
 Spring Boot – MockMvc JUnit
 Spring Boot – Docker Deployment