Spring Boot Scala Thymeleaf Example Tutorial

In this tutorial, you will learn how to develop a simple web application using Spring Boot and Scala.
Scala is one of the most popular JVM-based programming languages. It mixes functional programming and object-oriented programming idioms into a single language.

1. Creating Spring Boot Project

Spring Initializer (http://start.spring.io) doesn’t provide support for Scala yet, but you can create Spring Boot applications using the Scala programming language by configuring appropriate plugins based on the build tool you are using.
If you want to use Maven as a build tool, you can use scala-maven-plugin to compile your Scala code. 

2. Add Maven Dependencies

Add the Web, Spring Data JPA, Thymeleaf, and H2 starter dependencies.
<?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>net.sourcecodeexamples</groupId>
    <artifactId>springboot-scala-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>springboot-scala-demo</name>
    <description>Demo project for Spring Boot</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/>
        <!-- lookup parent from repository -->
    </parent>
    <properties>
        <kotlin.compiler.incremental>true</kotlin.compiler.incremental>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <scala.version>2.11.1</scala.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-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</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>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>${scala.version}</version>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>src/main/scala</sourceDirectory>
        <testSourceDirectory>src/test/scala</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>3.2.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <jvmArgs>
                        <jvmArg>-Xms64m</jvmArg>
                        <jvmArg>-Xmx1024m</jvmArg>
                    </jvmArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

3. User.scala

Create a JPA entity called User.scala and add the following content to it:
import javax.persistence._

import scala.beans.BeanProperty

@Entity
@Table(name = "users")
class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @BeanProperty
    var id: Long = _

    @BeanProperty
    var name: String = _

    @BeanProperty
    var email: String = _

}
You are using the @BeanProperty to generate setters and getters for fields based on the JavaBean naming conventions.

4. UserRepository.scala

Now you’ll see how to create the Spring Data JPA repository for the User entity. As Scala doesn’t have interfaces, you are going to create UserRepository as a trait:
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.repository.query.Param

trait UserRepository extends JpaRepository[User, java.lang.Long] {
  def findByEmail(@Param("email") name: String): List[User]
}

5. HomeController.scala

Let's create a Spring MVC controller to show the list of users:
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation. {
    GetMapping
}

@Controller
class HomeController {
    @Autowired
    var repo: UserRepository = _

    @GetMapping(Array("/"))
    def home(model: Model): String = {
        model.addAttribute("users", repo.findAll())
        "home"
    }
}

6. data.sql

Here is a data.sql script to populate sample users:
delete from users;

insert into users(id, name, email) values
(1,'admin','admin@gmail.com'),
(2,'code','code@gmail.com'),
(3,'test','test@gmail.com');

7. src/main/resources/templates/home.html

Create the Thymeleaf view home.html to render users:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Users List</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<table>
    <thead>
    <tr>
        <th>Id</th>
        <th>Name</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="user : ${users}">
        <td th:text="${user.id}">Id</td>
        <td th:text="${user.name}">Name</td>
    </tr>
    </tbody>
</table>
</body>
</html>

8. Application 

Next, you are going to create the application main entry point class. As Scala doesn’t support static methods, you have to create a companion object and write the main() method:
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication

@SpringBootApplication
class Application {

}

object Application {
    def main(args: Array[String]) : Unit = {
        SpringApplication.run(classOf[Application], args:_*)
    }
}
Now you can run Application.main(), which starts your Spring Boot application and accesses it at http://localhost:8080/. You can also use below command to run this spring boot app:
springboot-scala-demo> mvn spring-boot:run
This shows a list of users.

Comments