Example of how SpringBoot integrates Kotlin to build Web services
- 2021-06-29 11:09:32
- OfStack
Today we are trying to integrate Kotlin with Spring Boot and have decided to build a very simple Spring Boot micro-service using Kotlin as a programming language.
Create a simple Spring Boot application.Here I will use maven to build the project:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
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.edurt.ski</groupId>
<artifactId>springboot-kotlin-integration</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>springboot kotlin integration</name>
<description>SpringBoot Kotlin Integration is a open source springboot, kotlin integration example.</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.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>
<!-- plugin config -->
<plugin.maven.kotlin.version>1.2.71</plugin.maven.kotlin.version>
</properties>
<dependencies>
<!-- spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- kotlin -->
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
<plugin>jpa</plugin>
<plugin>all-open</plugin>
</compilerPlugins>
<pluginOptions>
<option>all-open:annotation=javax.persistence.Entity</option>
</pluginOptions>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${plugin.maven.kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-noarg</artifactId>
<version>${plugin.maven.kotlin.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>kapt</id>
<goals>
<goal>kapt</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/main/kotlin</sourceDir>
</sourceDirs>
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${project.parent.version}</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Add all required dependencies:
lib Package for kotlin-stdlib-jdk8 kotlin jdk8 kotlin-reflect kotlin Reflection PackA simple application class:
package com.edurt.ski
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class SpringBootKotlinIntegration
fun main(args: Array<String>) {
runApplication<SpringBootKotlinIntegration>(*args)
}
Add Rest API interface functionality
Create an HelloController Rest API interface, we only provide a simple get request to get hello, kotlin output information:
package com.edurt.ski.controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class HelloController {
@GetMapping(value = "hello")
fun hello(): String {
return "hello,kotlin"
}
}
Modify the SpringBootKotlinIntegration file to add the following settings to the scan path
@ComponentScan(value = [
"com.edurt.ski",
"com.edurt.ski.controller"
])
Add page functionality
Modify the pom.xml file to increase the following page dependencies
<!-- mustache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mustache</artifactId>
</dependency>
Create the templates folder under the src/main/resources path
Create a page file named hello.mustache under the templates folder
<h1>Hello, Kotlin</h1>
Create Page Converter HelloView
package com.edurt.ski.view
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
@Controller
class HelloView {
@GetMapping(value = "hello_view")
fun helloView(model: Model): String {
return "hello"
}
}
Browser access to http://localhost:8080/hello_view will see the page content
Add data persistence
Modifying the pom.xml file adds the following dependencies (we use the h2 in-memory database for testing purposes)
<!-- data jpa and db -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
Create User entity
package com.edurt.ski.model
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id
@Entity
//class UserModel(
// @Id
// @GeneratedValue
// private var id: Long? = 0,
// private var name: String
//)
class UserModel {
@Id
@GeneratedValue
var id: Long? = 0
get() = field
set
var name: String? = null
get() = field
set
}
Create UserSupport dao Database Operations Tool Class
package com.edurt.ski.support
import com.edurt.ski.model.UserModel
import org.springframework.data.repository.PagingAndSortingRepository
interface UserSupport : PagingAndSortingRepository<UserModel, Long> {
}
Create UserService service class
package com.edurt.ski
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class SpringBootKotlinIntegration
fun main(args: Array<String>) {
runApplication<SpringBootKotlinIntegration>(*args)
}
0
Create UserServiceImpl implementation class
package com.edurt.ski
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class SpringBootKotlinIntegration
fun main(args: Array<String>) {
runApplication<SpringBootKotlinIntegration>(*args)
}
1
Create user UserController to persist data
package com.edurt.ski
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class SpringBootKotlinIntegration
fun main(args: Array<String>) {
runApplication<SpringBootKotlinIntegration>(*args)
}
2
Use the console window to execute the following commands to save data
curl -X POST http://localhost:8080/user/save/qianmoQ
Return results received
{"id":1,"name":"qianmoQ"}
Indicates that the data was saved successfully
Add data read rendering
Modify UserService to add the following code
package com.edurt.ski
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class SpringBootKotlinIntegration
fun main(args: Array<String>) {
runApplication<SpringBootKotlinIntegration>(*args)
}
4
Modify UserServiceImpl to add the following code
package com.edurt.ski
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class SpringBootKotlinIntegration
fun main(args: Array<String>) {
runApplication<SpringBootKotlinIntegration>(*args)
}
5
Modify UserController to add the following code
package com.edurt.ski
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class SpringBootKotlinIntegration
fun main(args: Array<String>) {
runApplication<SpringBootKotlinIntegration>(*args)
}
6
Create UserView file to render User data
package com.edurt.ski
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class SpringBootKotlinIntegration
fun main(args: Array<String>) {
runApplication<SpringBootKotlinIntegration>(*args)
}
7
Create an user.mustache file to render data (parse the returned data yourself)
{{users}}
Browser access to http://localhost:8080/user_view to see the page content
Add Unit Function
Modify the pom.xml file to add the following dependencies
package com.edurt.ski
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class SpringBootKotlinIntegration
fun main(args: Array<String>) {
runApplication<SpringBootKotlinIntegration>(*args)
}
9
Create an UserServiceTest file to test the UserService functionality
package com.edurt.ski
import com.edurt.ski.service.UserService
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.data.domain.PageRequest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserServiceTest(@Autowired private val userService: UserService) {
@Test
fun `get all`() {
println(">> Assert blog page title, content and status code")
val entity = this.userService.getAll(PageRequest(0, 1))
print(entity.totalPages)
}
}
Source address: GitHub