dcsimg
 

Creating Standalone Web Applications with Spring Boot

Monday Mar 19th 2018 by Manoj Debnath

Learn how Spring can be used to create a Web application packaged with a Web server that runs with a single click.

Spring's Web framework provides necessary tools to build a Web application that addresses concerns such as state management, workflow, validation, and many other important aspects that are specific to Web application development. This article walks through an example of developing a CRUD-based, simple Web application that uses technologies such as REST and JPA while building it from scratch.

Overview

The basis of Web development in Spring is supported by its MVC framework. This framework is built upon the Model-View-Controller pattern from where it gets the name Spring MVC. It provides the Web development support APIs within the umbrella of Spring. It also enables building Web applications that are flexible and loosely coupled, just like the Spring framework. Before we begin, we must have an idea about how Spring MVC works.

To state briefly, a HTTP request received from the client is funneled through a servlet which delegates the responsibilities of request processing to other components. This is called a front controller. In Spring MVC, the DispatcherServlet class acts as the front controller and dispatches the HTTP request to the appropriate controller. A controller in Spring is a component that processes the request. But, the problem is that there can be several components. The DispatcherServlet must be able figure out the right component. Therefore, it takes the help of one or more handler mappings. The handler mapping maps according to the request URL and enables mapping to the correct controller. The controller then typically delegates the responsibility of request processing with the payload to one or more business service classes and waits for the result. It is this business service class that performs the actual request processing.

Once the controller receives the resulting information, it is packaged into model data. The controller's responsibility ends with naming the view that renders the output. It therefore sends the request, along with view name, back to DispatcherServlet. The view name, however, does not specify the technology used to process the view. Therefore, it clearly decouples the concerns of the view from its implementation. The view may be built using JSP, or any other client-side application development framework. Some popular names are AngularJS, Ember, Backbone, and so forth.

The model information is raw data, typically in a JSON structure that must be rendered in an HTML format by some sort of client-side processing. It is this processing which is done by the client-side frameworks.

We'll build the application using Spring Boot in Spring Tool Suite (STS) as follows:

  1. Open STS. Select File, New, Spring Starter Project. (The Internet must be "on.")
  2. Provide the necessary project details, for example (see Figure 1):
    • Name: spring-boot-mvc-jpa
    • Group: org.mano.springboot-jpa
    • Artefact: spring-boot-mvc-jpa
    • Package: org.mano.springboot-jpa

      New Spring Starter Project
      Figure 1: New Spring Starter Project

  3. Select the following Project dependencies, as shown in Figure 2:
    • Web: This includes the SpringMVC framework with REST supported
    • JPA: This include Hibernate and JPA APIs
    • H2:This includes the H2 embedded database

      The Project dependencies
      Figure 2: The Project dependencies

  4. Finish.

The Project Structure in STS is depicted in Figure 3:

The Project Structure in STS
Figure 3: The Project Structure in STS

The dependencies in pom.xml are as follows:

<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-web</artifactId>
   </dependency>
   <dependency>
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId>
      <scope>runtime</scope>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
   </dependency>
</dependencies>

Database connectivity configurations are generally set in the application.properties file The contents that serves that purpose is as follows:

# creates a database named employee_db in the current project
# directory
spring.datasource.url=jdbc:h2:./employee_db
# username to access the database is set to 'root'
spring.datasource.username=root
# password for the username 'root' is set to 'root'
spring.datasource.password=root

# spring.jpa.show-sql=true shows the SQL while Hibernate
spring.jpa.show-sql=true
# create and drops the database on every run
spring.jpa.hibernate.ddl-auto=create-drop

spring.h2.console.enabled=true
spring.h2.console.path=/employee_db

We'll have a model class called Employee designated with JPA annotation and a JPA repository interface called EmployeeRepository, which provides the database CRUD operation automatically, thanks to the JpaRepository interface. The JpaRepository is a JPA-specific extension of the Repository interface, The Repository is a central repository marker interface, which can selectively expose CRUD methods by simply declaring methods of the same signature as those declared in CrudRepository. The CrudRepository is an interface for generic CRUD operations on a repository.

package org.mano.springbootjpa.models;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "emp_tbl")
public class Employee {

   @Id
   @GeneratedValue
   @Column(name = "emp_id")
   private int id;
   @Column(name = "emp_name")
   private String name;
   @Column(name = "emp_skillset")
   private String skillSet;
   @Column(name = "emp_email")
   private String email;

   public Employee() {
      super();
   }

   public Employee(String name, String skillSet, String email) {
      super();
      this.name = name;
      this.skillSet = skillSet;
      this.email = email;
   }

   public int getId() {
      return id;
   }

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

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public String getSkillSet() {
      return skillSet;
   }

   public void setSkillSet(String skillSet) {
      this.skillSet = skillSet;
   }

   public String getEmail() {
      return email;
   }

   public void setEmail(String email) {
      this.email = email;
   }

}

package org.mano.springbootjpa.repositories;

import org.mano.springbootjpa.models.Employee;
import org.springframework.data.jpa.repository.JpaRepository;

public interface EmployeeRepository extends
   JpaRepository<Employee, Integer>{

}

Because it is a small project, we'll implement the business logic within the controller class, called EmployeeController. In a production-ready application, this is certainly avoided. The business logic classes are separated from the controller classes, but for simplicity we'll do everything in the controller class.

If we want our controller classes to be a REST controller, we may designate it with the @RestController annotation; otherwise, we may use the @Controller annotation. In fact, there is little difference between @RestController and @Controller according to the Spring API Documentation. The @RestController is a convenience annotation that includes @Controller and @ResponseBody.

In the EmployeeController class, we have injected an EmployeeRepositoryinstance with an @Autowired annotation so that we can invoke the automatic database operation provided by the repository class due to the JpaRepository interface. The @Autowired annotation marks the EmployeeRepositoy instance to be autowired by Spring's dependency injection facilities. We also have provided the relevant URL mapping to the appropriate functions. For example: @GetMapping retrieves information with an HTTP GET request, @DeleteMapping makes an HTTP DELETE request, @PostMapping maps to the HTTP POST request, and @PutMapping maps to the HTTP PUT request.

package org.mano.springbootjpa.controllers;

import java.util.List;

import org.mano.springbootjpa.models.Employee;
import org.mano.springbootjpa.repositories.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/payroll")
public class EmployeeController {

   @Autowired
   private EmployeeRepository employeeRepository;

   @GetMapping("/employees")
   public List<Employee> getUsers(){
      return employeeRepository.findAll();
   }

   @GetMapping("/employee/{id}")
   public Employee getUser(@PathVariable int id){
      return employeeRepository.findOne(id);
   }

   @DeleteMapping("/employee/{id}")
   public Boolean deleteUser(@PathVariable int id){
      employeeRepository.delete(id);
      return true;
   }

   @PostMapping("/employee")
   public Employee createUser(Employee user){
      return employeeRepository.save(user);
   }

   @PutMapping("/employee")
   public Employee updateUser(Employee user){
      return employeeRepository.save(user);
   }

}

Finally, the Spring Boot loader class from where the application begins execution is written as follows:

package org.mano.springbootjpa;

import org.mano.springbootjpa.models.Employee;
import org.mano.springbootjpa.repositories.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure
   .SpringBootApplication;

@SpringBootApplication
public class SpringBootMvcJpaApplication implements
      CommandLineRunner {

   @Autowired
   private EmployeeRepository employeeRepository;

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

   @Override
   public void run(String... arg0) throws Exception {
      employeeRepository.save(new Employee
         ("Brad", "Java, C++", "brad@abcmail.com"));
      employeeRepository.save(new Employee
         ("Roy", "Cryptography", "roy@xyzmail.com"));
      employeeRepository.save(new Employee
         ("Henry", "Algorithm", "henry@xyzmail.com"));
      employeeRepository.save(new Employee
         ("Neel", "AI", "neel@xyzmail.com"));
      employeeRepository.save(new Employee
         ("Maya", "PR", "maya@xyzmail.com"));

   }

}

We now have implemented the CommandLineRunner interface to feed some dummy data into the database. The CommandLineRunner is an interface provided by Spring Boot to run a specific segment of code prior the application's start. The interface contains a run method which, once overridden, is invoked prior to the SpringApplication.run() method completing its execution.

Finally, to run the application, right-click the project, select Run As, and then select Spring Boot App, as you can see from Figure 4.

Running the application
Figure 4: Running the application

Observe that the browser shows data in a JSON format, which is typically what we wanted by designating the controller class with the @RestController annotation. Now, if we want to display the output in a user-friendly manner, we'll have to implement the view using client-side JavaScript such as AngulaJS, Ember, and so on, or by using JSP, which requires another write-up like this. Alternatively, one can use Postman or another HTTP client that are popularly used for testing Web services.

Therefore, note that without any client implementation, the preceding project is limited to testing getUser() and getUsers() controller functions only.

Conclusion

The Spring MVC provides a powerful, yet flexible, Web development framework. A POJO class can be converted into a REST controller by using annotation. Above all, the Spring Boot Project has leveraged Web application development to a simple programming model. The simple application developed in this article perhaps will give you an idea about what goes where and how to develop a Web application using Spring Boot.

Home
Mobile Site | Full Site