KotlinをSpringBootと一緒にEclipseで使ってみた

# 前書き  
Spring 5で、Kotlinのサポートも入るようだが、とりあえず現行に組み合わせて見て感覚を確かめたかった。  


# 作業対象
* Java 8
* Kotlin 1.1.2-4
* eclipse Pleiades 4.6
* plugin
    * Spring Tool Suite(STS) for Eclipse 3.8.4
    * Kotlin Plugin for Eclipse 0.8.2 
* Spring boot 1.5.3
* thymeleaf

# eclipseのインストール
0. 以下から落とす。  
http://mergedoc.osdn.jp/  
bit数はOS依存、Java版Full Edition  
0. 任意のフォルダに展開する。

# プラグインのインストール
0. メニューバー ヘルプ(H)
0. Eclipse マーケットプレース(M)  
   ここで新たにウィンドウが開く
0. 検索タブ 検索(I) 
0. 「kotlin」と入力
0. Go(G)  
  「Kotlin Plugin for Eclipse」が出る
0. インストール  
    画面が切り替わる
0. 使用条項の条件に同意します。(A)
0. 完了(F)
0. セキュリティ警告が表示されるので OK
0. 再起動要求が表示されるので はい(Y)
0. ここまでと同様の手順で「sts」を検索しインストールする。

# プロジェクトの作成
0. メニューバー ファイル(F)
0. その他(O) Ctrl+N  
   ここで新たにウィンドウが開く
0. 「Spring スターター・プロジェクト」を選択
0. 次へ(N)  
    ※型がMaven 言語がJavaになっているはず  
    ※名前や説明は任意
0. 次へ(N)   
0. WebとThymeleafを選択
0. 完了(F)   

## 依存の修正(pom.xml)
### propertiesに以下の要素を追加する。  
`<kotlin.version>1.1.2-4</kotlin.version>`

### dependencyに以下の要素を追加する。

```
		<dependency>
			<groupId>org.jetbrains.kotlin</groupId>
			<artifactId>kotlin-stdlib</artifactId>
			<version>${kotlin.version}</version>
		</dependency>
```

### build->pluginsに以下の要素を追加する。  

```
        <plugin>
            <artifactId>kotlin-maven-plugin</artifactId>
            <groupId>org.jetbrains.kotlin</groupId>
            <version>${kotlin.version}</version>

            <executions>
                <execution>
                    <id>compile</id>
                    <goals> <goal>compile</goal> </goals>
                </execution>

                <execution>
                    <id>test-compile</id>
                    <goals> <goal>test-compile</goal> </goals>
                </execution>
            </executions>
        </plugin>
```

※最終的なpom.xmlは末尾参照

# 作成したプロジェクトの挙動確認
## 起動方法
0. パッケージの上で右クリック
0. コンテキストメニューから実行をたどる
0. Spring Boot アプリケーション  
※Alt+Shift+xを押してからBでも起動できる。

## spring
1. パッケージに以下のクラスを追加する。
2. http://localhost:8080/ にアクセスして「hello world」と出ればOK

```java:RootController.java
package com.example.demo;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RootController {
	@RequestMapping(path = "/")
	public String root() {
		return "hello world";
	}
}
```

## kotlin
0. パッケージに以下のクラスを追加する。
0. RootControllerに次のメソッドを追加する。
0. http://localhost:8080/kt?str=value にアクセスして"{"str":"value"}"と出ればOK

```kotlin:Form.kt
package com.example.demo

data class Form (
	var str:String = ""
)
```

```java:追加メソッド
	@RequestMapping(path = "/kt")
	public Object kt(Form form) {
		return form;
	}
```

## thymeleaf
0. パッケージに以下のクラスを追加する。
0. /src/main/resources/templatesにhtmlを追加する。
0. http://localhost:8080/tlにアクセスしてstr stringと箇条書きで3,2,1と出ればOK

```java:TemplateController.java
package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class TemplateController {
	@RequestMapping(path = "tl")
	public String tl(Model model) {
		model.addAttribute("ktData", new Data());
		return "tl";
	}
}

```

```html:tl.html
<html>
<h1>Data values?</h1>
<div>
	<span>str</span>
	<span th:text="${ktData.str}"></span>
</div>
<div>
	<span>numbers</span>
	<ul th:each="value:${ktData.numbers}">
		<li th:text="${value}"></li>
	</ul>
</div>
</html>
```

# 感想
* data classはすぐにでも使うことは可能に思える。  
    * thymeleafに食わせても素直に動いてくれるので特に問題は無さそう。
* ビルド環境を整える上で、基本的にプラグイン1つとpomだけで対応できるのは大変よい。
* Eclipseだとkotlinの補完が面倒（不慣れというのも関係あるかも）
    * 書けるか、書けないかだとEclipseでもそれなりに書けると思う。
* JavaDocに相当するKDoc？が現状のプラグインでは表示できないので、data class以外だと厳しいと思う。
* Kotlinでコントローラー書こうとして```@RequestMapping(path = "/") endpoint(): Object{･･･}```だとエラー出てたが何が悪かったんだろうか、、、

# ソース類

```xml:pom.xml
<?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>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>demo</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.3.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<java.version>1.8</java.version>
		<encoding>UTF-8</encoding>
		<project.build.sourceEncoding>${encoding}</project.build.sourceEncoding>
		<project.reporting.outputEncoding>${encoding}</project.reporting.outputEncoding>
		<kotlin.version>1.1.2-4</kotlin.version>
	</properties>

	<dependencies>
		<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>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.jetbrains.kotlin</groupId>
			<artifactId>kotlin-stdlib</artifactId>
			<version>${kotlin.version}</version>
		</dependency>

	</dependencies>

	<build>
		<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>
				<version>${kotlin.version}</version>

				<executions>
					<execution>
						<id>compile</id>
						<goals>
							<goal>compile</goal>
						</goals>
					</execution>

					<execution>
						<id>test-compile</id>
						<goals>
							<goal>test-compile</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>
```

# 参考先
* https://kotlinlang.org/docs/reference/using-maven.html