Spring Application Coding

Building Spring Boot Application with FreeMarker, JPA, REST and Groovy Spock Tests

In this simple example I would like to show you how to build an application using a few technologies like Spring Boot with FreeMarker Java Template engine for rendering the view, Java Persistence API for storing our objects into the database and simple REST API for application’s data manipulation. We will add some Groovy integration tests using Spock testing and specification framework. Our application functionality will be very simple. We will be able to add users using both rendered HTML page and REST API and store them into in-memory Java SQL database called H2. The list of users will be displayed on the main page.

Dependencies

Let’s start from Maven dependencies which we will add to our pom.xml file. The main dependency is Spring Boot with Jetty server instead of Apache Tomcat:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

We will also need FreeMarker dependency:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

and JPA with H2 Java in-memory database:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
</dependency>

For integration tests we need Groovy, Spock framework and HTTPBuilder which is an Easy HTTP client for Groovy:

<dependency>
  <groupId>org.codehaus.groovy</groupId>
  <artifactId>groovy-all</artifactId>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.spockframework</groupId>
  <artifactId>spock-core</artifactId>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.codehaus.groovy.modules.http-builder</groupId>
  <artifactId>http-builder</artifactId>
  <version>0.7.1</version>
  <scope>test</scope>
</dependency>

Application

Let’s start from the main application’s class which will run our Spring application. With Spring Boot it is straightforward:

@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableJpaRepositories
public class Application {
  
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

In order to be able to use JPA Repositories, we have to add @EnableJpaRepositories Java annotation.

User Repository

In the next step we will implement our User Repository which will store User objects in the database. Let’s create User entity first as a POJO object with JPA annotations. The User object will contain name and id attributes.

@Entity
public class User {
  
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private String id;
  private String name;
  
  protected User() {
    
  }
  
  public User(String name) {
    this.name = name;
  }

  public String getId() {
    return id;
  }

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

  public String getName() {
    return name;
  }

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

Now comes the coolest part which is the implementation of the Users repository. Using Spring Boot we do not need to… provide the implementation :-). What we need to do is just to create a Java interface which extends JpaRepository Spring interface. Spring will magically generate the implementation of CRUD methods we want.

public interface UserServiceRepository extends JpaRepository<User, Long> {
  public List<User> findAll();
  public User save(User user);
  public List<User> findByName(String name);
}

View Controller

Spring’s Controller will be used for providing data for our FreeMarker template (web page) and will handle adding new Users from the web page form. In the Controller we must inject our User Repository so that we can obtain the list of all users to be displayed and store a new User into the database. We will implement two methods to cover these functionalities.

@Controller
public class HelloController {
  
  @Autowired
  private UserServiceRepository repo;
  
  @RequestMapping("/")
  public String index(Map<String, Object> model) {
    PageRequest page = new PageRequest(0, 20, new Sort(new Order(Direction.ASC, "name")));
    model.put("users", repo.findAll(page).getContent());
    return "hello";
  }
  
  @RequestMapping(value = "/add", method = RequestMethod.POST)
  public String add(@ModelAttribute("user") User user) {
    if (isUserValid(user)) {
       repo.save(user);
    }
    return "redirect:/";
  }

  private boolean isUserValid(User user) {
    return null != user && null != user.getName() && !user.getName().isEmpty();
  }
}

The index() method returns “hello” String which is the name of the FreeMarker template file used for rendering the web page. The hello.ftl template file has to be added to the class path. The add() method handles HTTP POST requests which will come from the web page. When the request is handled, User will be added into the repository after validation. Then we will be redirected to the main page.

FreeMarker Template

In our main web page we will display the list of Users added to our Repository and we will also display a form which can be used for adding new Users. This is the code of the hello.ftl template file:

<!DOCTYPE html>
<html lang ="en">
<body>
  <h1> List of users</h1>
  <#if users?has_content>
    <ul>
      <#list users as u>
        <li>Id: ${u.getId()}, Name: ${u.getName()}</li>
      </#list>
    </ul>
  <#else>
    No users added yet! Please use REST service to do so, for e.g. POST {"name": "John"} using /users or the form below.
  </#if>
  
  </br></br>
  
  <fieldset>
        <legend>Add User</legend>
        <form name="user" action="add" method="post">
            Name: <input type="text" name="name" /> <br/>
        <input type="submit" value="Save" />
        </form>
    </fieldset>
</body>
</html>

REST Controller

Together with the Controller which is used with the view we will implement a REST Controller for adding Users to the repository via HTTP POST requests. JSON objects which represent the User will be send as a POST body. The implementation is very simple:

@RestController
public class UserController {
  
  @Autowired
  private UserServiceRepository repo;
  
  @RequestMapping(value = "/users", method = RequestMethod.POST)
  public User addUser(@RequestBody User user) {
    repo.save(user);
    return user;
  }
}

Integration Tests

After running our application we may perform some tests. Let’s implement two tests using Spock framework. Our tests will be checking the RestController used for adding new Users to the repository. The first test checks if a User is added properly into the repository and the second one expects 405 HTTP status since GET method for given URL is not allowed. Tests will be implemented in Groovy:

class UserServiceRepositoryTest extends Specification {
  
  def "should return 200"() {
    setup:
        def endpoint = new RESTClient('http://localhost:8080/users')
    
    when:
        def resp = endpoint.post(
          body : '{"name" : "John"}',
          requestContentType : 'application/json'
        )
    
    then:
        with(resp) {
          status == 200
        }
  }

  def "should return 405"() {
    setup:
         def endpoint = new RESTClient("http://localhost:8080/users")
    when:
        def resp = endpoint.get(
           requestContentType: 'application/json'
        )
    then:
        def e = thrown(HttpResponseException)
           e.message == 'Method Not Allowed'
  }
}

When application is running let’s open a browser and enter http://localhost:8080/ URL. You should see the main page of our application:

Spring Boot Application

Now using http://localhost:8080/users URL we may send a HTTP POST request with body containing a User we want to add:

REST post request

Then after refreshing the page we should see our added User listed. We may also use the for for adding new users.

Spring Boot Application User Added

Summary

In this simple application we used many technologies. Spring Boot integrated them all together for us behind the scenes. Especially, we gain much productivity using JpaRepository interface. We don’t have to implement all CRUD methods but we may only list the signatures of the methods we want to use. The Spock testing framework is also a powerful tool following the Given-When-Then style of representing the tests. The whole application is available in my GitHub repository: https://github.com/mzimecki/MySpringBootExample.git. You may also download the code here:

Spring Boot Application (17 downloads)