Spring Bootのウェブアプリケーションのサンプル。
単純に画面をひとつ表示するサンプルを作ってみる。(Spring Boot 1.5.6)
Spring Initializr(テンプレートとしてThymeleafを使用。DevToolsも入れておく)を使ってソース一式を生成し、そこに必要なソースを追加していく。
build.gradleは以下のようになる。
buildscript { ext { springBootVersion = '1.5.6.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile('org.springframework.boot:spring-boot-starter-thymeleaf') runtime('org.springframework.boot:spring-boot-devtools') testCompile('org.springframework.boot:spring-boot-starter-test') }
ダウンロードしてきたdemoアプリケーションにはhtmlファイルが無いので、自分で作成する。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Hello Thymeleaf</title> </head> <body> <h1>Hello Thymeleaf</h1> </body> </html>
Thymeleafを使う場合、テンプレートファイルは普通のhtmlファイルとほぼ同じ。
ブラウザーから要求されたURIに対する処理を記述するのはControllerクラス。
package com.example.demo; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;
@Controller public class HelloController { @RequestMapping(path = "/hello") public String hello() { return "hello"; } }
Controllerクラスには、@Controllerアノテーションを付ける。
URIの処理をするメソッドには@RequestMappingアノテーションで処理対象URIのバスを指定する。
パスが「/hello」の場合、ブラウザーから「http://ホスト名:8080/hello」でアクセスされたときに呼ばれることになる。
メソッド名は何でもいい。
メソッドの戻り値の型をStringにしておくと、そこで返す値はhtmlファイルを指定した事になる。
つまり「hello」を返すとhello.htmlがブラウザーに返されることになる。
(もしhtmlファイルがtemplates/hoge/zzz.htmlなのであれば、それを示すメソッドの戻り値は「hoge/zzz」になる)
STSを使っている場合、パッケージエクスプローラー上でDemoApplication.javaを右クリックして「Run
As」→「Spring Boot App」を選択すれば、ウェブアプリケーションが起動する。
通常のEclipseの場合でも普通にDemoApplicationを実行すればウェブアプリケーションが起動する。
ブラウザーから「http://localhost:8080/hello
」を呼び出すと、HelloControllerが動いてhello.htmlが表示される(はず)。
コンソール上の停止ボタン(赤い四角いやつ)を押すとウェブアプリケーションは終了する。
Controller上で現在時刻を取得し、htmlで出力(画面に表示)してみる。
package com.example.demo; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping;
@Controller public class HelloController { private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss zzz");
@RequestMapping(path = "/hello") public String hello(Model model) { model.addAttribute("date", ZonedDateTime.now().format(FORMATTER)); return "hello"; } }
メソッドの引数にModelを追加する。
このModelにaddAttributeすると、その値がhtmlで取得できる。
ちなみにDateTimeFormatterはMTセーフなので、Conrollerクラスのstaticフィールドで保持してメソッド内で使っても問題ない。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Hello Thymeleaf</title> </head> <body> <h1>Hello Thymeleaf</h1> <p>時刻: <span th:text="${date}">2017/08/26 12:34:56 JST</span></p> </body> </html>
htmlファイル上は「${名前}
」でConrollerでModelにセットした値が取得できるのだが、それを指定する場所が独特。th:text
属性に書く。
th:text
属性の値は、実行時にはタグのボディー部に展開される。(元々ボディー部に書かれていた文は上書きされて消える)
つまりテンプレート上の「<span th:text="hoge">zzz</span>
」は実行時には「<span>hoge</span>
」になる。
(Thymeleafのこういう仕組みにより、テンプレートのhtmlファイルを直接ブラウザーで表示して、どう表示されるかを確認することが出来る(この場合にはタグのボディー部に書かれている内容が表示され、th:text
はブラウザーが解釈できない属性なので無視される))
画面(htmlのform)で入力された値をControllerで取得してみる。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Hello Thymeleaf</title> </head> <body> <h1>Hello Thymeleaf</h1> <p>時刻: <span th:text="${date}">2017/08/26 12:34.56 JST</span></p> <form action="#" th:action="@{/hello-submit}" method="post"> <p><input type="text" name="foo" /></p> <p><input type="submit" value="submit"/></p> </form> </body> </html>
formのinputは普通のHTML。
th:action
属性でsubmitボタンが押された際のURIを指定する。
「@{ }
」はThymeleafでURIを扱う際に付けるものらしい。
package com.example.demo;
〜 import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping;
@Controller public class HelloController { 〜
@RequestMapping(path = "/hello-submit") public String helloSubmit(@ModelAttribute("foo") String foo, Model model) { model.addAttribute("date", foo); return "hello"; } }
HttpRequestのパラメーターは、Controllerのメソッドの引数に@ModelAttributeアノテーションを付けるだけで受け取れる。
(@RequestParamアノテーションでもいいし、HttpServletRequestでrequest自体を受け取ることも出来なくはない)