時代遅れかもしれないSpring Web Flow入門 2

#環境のセットアップ
需要ないだろうが、まあ、続けます。
簡単な書籍情報を登録・参照するアプリを作ってみます。
ひとまず、通常のSpring MVC（Spring Boot）のコントローラを利用してメニュー画面を作ります。

##プロジェクト構成
src/main/java:プロジェクト本体
src/main/resources/templates:テンプレートのルート兼フロー定義のルート
src/test/groovy:テストはSpockで。
build.gradle:ビルドファイル。gradleで。

※自分はggts 3.6.3で動作確認しています。テストを実行するには、groovyコンパイラのバージョンを2.0にダウングレードする必要があります。gradleからはこのままでいけるはずです。

##buildファイル
gradleで。

```groovy:build.gradle
buildscript {
	ext {
		springBootVersion = '1.2.0.RELEASE'
	}
	repositories {
		// NOTE: You should declare only repositories that you need here
		mavenLocal()
		mavenCentral()
		maven { url "http://repo.spring.io/release" }
		maven { url "http://repo.spring.io/milestone" }
		maven { url "http://repo.spring.io/snapshot" }
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
	}
}

apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'eclipse'
//apply plugin: 'idea'
apply plugin: 'spring-boot'

def webFlowVersion = '2.4.1.RELEASE'

jar {
	baseName = 'flowApp'
	version =  '0.1.0'
}

run {
  systemProperties = System.properties
}

repositories {
	mavenCentral()
	maven { url "http://repo.spring.io/release" }
	maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}

dependencies {
	compile("org.springframework.boot:spring-boot-starter-thymeleaf")	
	compile ("org.springframework.webflow:spring-webflow:${webFlowVersion}")
	compile ("org.springframework.webflow:spring-js:${webFlowVersion}")
	
	
	testCompile("org.springframework.boot:spring-boot-starter-test")
	testCompile("org.spockframework:spock-spring:0.7-groovy-2.0")
	
}

task wrapper(type: Wrapper) {
	gradleVersion = '1.6'
}

```
##起動クラス

```java:flowapp/Application.java
package flowapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
	public static void main(String[] args) {
		new SpringApplication(Application.class).run(args);
	}
}

```

##コントローラ
```java:flowapp/controller/MenuController
package flowapp.controller;

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

@Controller
public class MenuController {
	@RequestMapping("/")
	public String menu(){
		return "menu";
	}
}
```
##テンプレート
```html:menu.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>メニュー画面</title>
</head>
<body>
	メニュー画面です。<br/>
	<a th:href="@{/search}">検索</a>
	<a th:href="@{/create}">登録</a>
</body>
</html>
```
##テスト
assertionは適当。

```groovy:flowapp/MenuControllerSpec.groovy
package flowapp;

import static org.junit.Assert.*

//static インポート以外は省略
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*
import static org.hamcrest.Matchers.*;

@ContextConfiguration(loader = SpringApplicationContextLoader.class,classes=[Application.class])
@WebAppConfiguration
class MenuControllerSpec extends Specification {

	@Autowired
	MenuController menuController;
	
	@Autowired
	WebApplicationContext wac;

	MockMvc mockMvc;

	def setup(){
		MockitoAnnotations.initMocks(this);
		this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
	}

	def "メニュー画面のテスト"(){
		when:"コンテキストルートにアクセスしたら"
		def pf=mockMvc
		.perform(get("/"))
		
		then:"メニュー画面が表示される。"
		pf
		.andExpect(status()
			.isOk())
		.andExpect(view().name("menu"))
		.andExpect(content().string(containsString("メニュー画面です。")))
	}
}
```