In this tutorial we will learn how to create a basic application using Spring Boot CLI. We will then import the application into an IDE to create a sample application which stores some data which is later retrieved by the SpringApplication class.

We wil start from Spring Command Line Interface. You can however surf to the Spring Initializr Web application if you prefer.
Our Web application, named samplewebapp, will require the following dependencies as specified by spring init:

$ spring init -dweb,data-jpa,h2   samplewebapp

Now let's check what has been created for us:


~/springboot:$ tree samplewebapp/
samplewebapp/
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── samplewebapp
    │   │               └── DemoApplication.java
    │   └── resources
    │       ├── application.properties
    │       ├── static
    │       └── templates
    └── test
        └── java
            └── com
                └── example
                    └── samplewebapp
                        └── DemoApplicationTests.java

This contains essentially the same project structure as what the Initializr. There is a DemoApplication.java class and a Test class for it:

package com.example.samplewebapp;

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

@SpringBootApplication
public class DemoApplication {

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

The good thing is that the spring init tool has already set the required dependencies for us in the project's pom.xml file:

    <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>

As it is, the application won't do much so let's add an Entity to our project named Person:

package com.example.samplewebapp;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;
    String name;
    String surname;
    
    public Person(String name, String surname) {
        super();
        this.name = name;
        this.surname = surname;
    }

    public Person() {
        super();    
    }

    public Long getId() {
        return id;
    }

    private void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }


    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", surname=" + surname + "]";
    }

}

One of the coolest features of Spring is the ability to create repository implementations automatically, at runtime, from a repository interface. Out of the box the repository interface already contains methods to find an Entity by id and to findAll Entity. We will add one more method named "findBySurname" which is defined in the following PersonRepository interface:

package com.example.samplewebapp;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface PersonRepository extends CrudRepository<Person, Long> {

    List<Person> findBySurname(String surname);
}

We are done with the backend. Now we will add in the @SpringBootApplication class some logic to insert a few Entity objects and retrieve them using the repository interface:

package com.example.samplewebapp;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SpringBootApplication
public class DemoApplication {
    private static final Logger log = LoggerFactory.getLogger(DemoApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
    @Bean
    public CommandLineRunner demo(PersonRepository repository) {
        return (args) -> {
            // save a couple of persons
            repository.save(new Person("Jack", "Smith"));
            repository.save(new Person("Joe", "Black"));
            repository.save(new Person("Martin", "Bauer"));


            // fetch all persons
            log.info("Persons found with findAll():");
            log.info("-------------------------------");
            for (Person person : repository.findAll()) {
                log.info(person.toString());
            }
            log.info("");

            // fetch an individual person by ID
            repository.findById(1L)
                .ifPresent(person -> {
                    log.info("Person found with findById(1L):");
                    log.info("--------------------------------");
                    log.info(person.toString());
                    log.info("");
                });

            // fetch persons by last name
            log.info("Person found with findBySurname('Black'):");
            log.info("--------------------------------------------");
            repository.findBySurname("Black").forEach(smith -> {
                log.info(smith.toString());
            });

            log.info("");
        };
    }
}

As you can see, we have used the CommandLineRunner interface to run the demo. As a matter of fact, Spring Boot provides two interfaces, CommandLineRunner and ApplicationRunner to run specific pieces of code when an application is started. These interfaces get called just before run() once SpringApplication completes. CommandLineRunner, used in our example, provides access to application arguments as string array.

Adding a REST Controller

We can further enhance our application by adding a Controller which will let us check the data available in the repository:

package com.example.samplewebapp;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class PersonController {

    @Autowired
    PersonRepository repository;

    @RequestMapping("/list")
    public List<Person> findAll() {

        List<Person> list = new ArrayList<Person>();
        repository.findAll().iterator().forEachRemaining(list::add);
        return list;

    }

    @RequestMapping("/one/{id}")
    public Optional<Person> findOne(@PathVariable Long id) {
        return repository.findById(id);

    }
}


You can run the application directly from your tool, for example if you are using Eclipse with Spring Tools, right click on the DemoApplication class and choose Run As > SpringBoot app

As an alternative, simply running:

mvn clean install spring-boot:run

or

java -jar target/samplewebapp-0.0.1-SNAPSHOT.jar 

Here is the output provided by the SpringApplication class:

Persons found with findAll():
-------------------------------

Person [id=1, name=Jack, surname=Smith]
Person [id=2, name=Joe, surname=Black]
Person [id=3, name=Martin, surname=Bauer]

Person found with findById(1L):
--------------------------------
Person [id=1, name=Jack, surname=Smith]

Person found with findBySurname('Black'):
--------------------------------------------
Person [id=2, name=Joe, surname=Black]

And you can check it through the available Controller as follows:

curl -s http://localhost:8080/list | jq
[
  {
    "id": 1,
    "name": "Jack",
    "surname": "Smith"
  },
  {
    "id": 2,
    "name": "Joe",
    "surname": "Black"
  },
  {
    "id": 3,
    "name": "Martin",
    "surname": "Bauer"
  }
]

And:

curl -s http://localhost:8080/one/1 | jq
{
  "id": 1,
  "name": "Jack",
  "surname": "Smith"
}

In this tutorial we have learned how to develop a basic application using Spring Boot API and javax.persistence API to store some data and use a repository class to retrieve them.

Source code: https://github.com/fmarchioni/masterspringboot/tree/master/jpa/samplewebapp

FREE WildFly Application Server - JBoss - Quarkus - Drools Tutorials