Kotlin is a jVA-BASED development language launched by Jetbrain, the developer of IntelliJ IDEA. The goal is to simplify the tedious design in Java and integrate it seamlessly with Java. I have been trying to use it in the unit test before. Try writing Spring Boot scaffolding.
Statically typed programming language for the JVM, Android and the Browser
Project introduction
The long-term goal is to develop a complete Spring Boot application using Kotlin, with minimal scaffolding currently in place.
In this practice, the use of Gradle Docker plug-in is added to complete the whole process from development, testing, packaging to releasing docker images with Gradle one-stop.
The project structure
SpringBootKotlon │ ├ ─ ─ ─ the build.gradle└ ─ ─ ─ the SRC ├ ─ ─ ─ the main │ ├ ─ ─ ─ docker │ ├ ─ ─ ─ Java │ ├ ─ ─ ─ kotlin │ └ ─ ─ ─ resources │ └ ─ ─ ─ the config/application.properties├── heavy exercises ─ heavy exercisesCopy the code
The package names are the same under Java, Kotlin, and Resources in the main directory. This means that classes in kotlin/com/app and Java /com/app are referenced in the same package by classpath.
Create a Spring Boot project
For details about how to create a SpringBoot project, see Implementing RESTful Framework Applications using Gradle and SpringBoot.
In order to support kotlin project build.gradle need to add kotlin support, and configure the Docker plug-in.
buildscript {
ext.kotlin_version = '1.1.0'
ext.spting_boot_version = '1.5.2. RELEASE'. . dependencies { classpath"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath("org.springframework.boot:spring-boot-gradle-plugin:$spting_boot_version")}}... . apply plugin:"kotlin"
apply plugin: 'org.springframework.boot'
dependencies{... . compile"org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
}
sourceSets{
main{... . kotlin {srcDir"src/main/kotlin"} } test{ ... .kotlin {srcDir "src/test/kotlin"}}}Copy the code
After the configuration, run Gradle Idea and download the gradle dependency packages. In the repositories using domestic mirror and self-built local nexus, can speed up the dependent package download maven {url ‘http://maven.aliyun.com/nexus/content/groups/public/’}
After configuring sourceSets to add kotlin’s package, you can create a Gradle task that automatically creates a directory for sourceSets. Gradle createJavaProject creates a directory for the specified set based on the path configured in sourceSets.
task createJavaProject << {
sourceSets*.java.srcDirs*.each { it.mkdirs() }
sourceSets*.kotlin.srcDirs*.each { it.mkdirs() }
sourceSets*.resources.srcDirs*.each { it.mkdirs()}
}Copy the code
Run the Spring Boot program
The application entry class of the project is implemented in Kotlin language. There are no static methods in Kotlin, so if you want to implement main, there are two methods: one is to write main outside the class; Or, with companion Object {}, write the methods that need to be called statically in {}.
@SpringBootApplication
open class SpringBootKotlinApplication
fun main(args: Array<String>){
SpringApplication.run(SpringBootKotlinApplication::class.java.*args)
}Copy the code
Compared to Spring MVC, Spring Boot avoids cumbersome and error-prone XML configuration files in Spring MVC with simple annotations and application.properties configuration. Greatly simplifies spring Boot configuration. It is worth mentioning that application profiles can also be used with YAML files.
Application configuration file description
port
You can specify the port to bind to the Spring Boot runtime by setting the server.port property in the configuration file.
freemarker
Spring. Freemarker.* is a freemarker configuration provided by Spring Boot. You can configure the same properties as annotations or XML files. Introduction of org. Springframework. The boot: spring – the boot – starter – freemarker this package.
In addition, the Application configuration file of Spring Boot can also configure various common third-party tools or libraries, including databases. It should provide a series of starter packages that wrap annotations and configuration processes.
Once configured, you can write the Spring MVC controller code in the subdirectory of the Application class.
Write a restful controller
A basic RestController code is as follows:
@RestController
@RequestMapping(value = "/api/data")
class DataController {
@RequestMapping(value = "",method = arrayOf(RequestMethod.GET,RequestMethod.PUT))
fun index(a):Map<String,Any>{
val resultMap = HashMap<String,Any>()
resultMap["status"] = true
resultMap["msg"] = "success"
return resultMap
}
@RequestMapping(value = "show",method = arrayOf(RequestMethod.PUT),consumes = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
fun test(@RequestBody reqMap:Map<Any,Any>):Map<Any,Any>{
return reqMap
}
}Copy the code
Code interpretation:
- Kotlin uses arrayof to initialize arrays;
- For variables that do not specify a type or that are of type Obejct, Kotlin uses type Any
- The method method allows you to specify the request header for the specified type
- As consumes, you can specify that the contentType that you accept is in the JSON format
- If the request is in JSON format, use ResponseBody to receive the JSON object
After all the code is complete, run Gradle bootRun to start the service.
curl 'http://localhost:8080/api/data/show' \ -X 'PUT' \ -H 'content-type: application/json' \ -H 'accept: application/json' \ --data-binary '{"data":"hello"."who":"echo"}' --compressedCopy the code
Test the Spring Boot program
Both Spring Boot and Kotlin provide powerful test suites that integrate well with JUnit for integration testing and unit testing. Write some basic integration tests to check that the interface works.
Spring Boot Starter Test integrates JUnit, Mockito, AssertJ, Hamcrest, Spring Test & Spring Boot Test to easily start testing
@RunWith(SpringJUnit4ClassRunner::class)
@WebMvcTest(HomeController::class)
class HomeControllerStandaloneTest {
@Autowired
private var mvc: MockMvc? = null
@Test
@Throws(Exception::class)
fun indexTest() {
mvc!!!!!.perform(MockMvcRequestBuilders.get("/").accept(MediaType.TEXT_HTML))
.andExpect(status().isOk)
.andExpect(model().attributeExists("data"))
.andExpect { content(a).string(containsString("<title>Spring Boot Kotlin</title>"))}}}Copy the code
MockMvc can dependency inject bindings to the HomeController controller annotated by WebMvcTest and then mock requests for the specified controller. AndExpect method to check whether the header and body of response meet the test expectation.
Source code: github.com/liuwill-pro…