Help us understand the problem. What is going on with this article?

【SpringBoot入門】thymeleafを使ってフォーム送信

目的

Spring Quickstart Guideを取り組み終えた方、SpringBootを学び始めた方、復習をしたい方に向けて、

公式ガイドHandling Form Submissionを実際に取り組み学んだことを共有します。

完成形はこちらになります。

Form画面で入力された値をResult画面で表示させるという処理を実装していきます。

スクリーンショット 2020-07-08 13.44.23.png

スクリーンショット 2020-07-08 13.44.30.png

開発環境、これまでのおさらいは以下になります。

開発環境
OS: macOS Mojave バージョン10.14.6
テキストエディタ: Visual Studio Code(以下VSCode)
Java: 11.0.2

QuickstartGuideのおさらいはこちらから
Building a RESTful Web Service編のおさらいはこちらから
Consuming a RESTful Web Service編のおさらいはこちらから
Accessing Data with JPA編のおさらいはこちらから

1.SpringBoot projectを始めよう!

まずは、spring initializrにアクセスします。

1.ADD DEPENDENCIESボタンをクリックして、Spring WebThymeleafを追加。
2.Artifact, Nameは、handling-form-submissionに変更。
3.Javaを11に変更。

そしてGENERATEボタンをクリックしてZipファイルをダウンロードします。

スクリーンショット 2020-07-08 9.35.18.png

ダウンロードしたZipファイルを展開したら準備完了です。

2.コードを追加しよう!

先ほどのフォルダをVSCodeで開きます。
拡張機能のJava Extension Packのインストールの推奨します。と言われるのでインストールしておきましょう。

スクリーンショット 2020-06-30 10.08.25.png

GreetingController.javaを作成しよう!

src/main/java/com/example/handlingformsubmission/ にGreetingController.javaファイルを作成します。

スクリーンショット 2020-07-08 9.55.33.png

公式を参考にコードを追加します。

GreetingController.java
package com.example.handlingformsubmission;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class GreetingController {

  @GetMapping("/greeting")
  public String greetingForm(Model model) {
    model.addAttribute("greeting", new Greeting());
    return "greeting";
  }

  @PostMapping("/greeting")
  public String greetingSubmit(@ModelAttribute Greeting greeting) {
    return "result";
  }

}

追加したコードを深掘りしていきます。

@Controller

GreetingController.java
@Controller
public class GreetingController {
  // 省略
}

@Controllerというアノテーションをつける事によってSpringBootは、このクラスをコントローラとして扱ってくれます。
Viewに遷移してHTMLを作成するので、後述するメソッドの戻り値にViewを指定しなければいけません。

今回は登場しませんが、@RestControllerというアノテーションも同様にコントローラとして扱ってくれますが、Viewに遷移せずメソッドの戻り値がレスポンスのコンテンツになります。

②greetingFormメソッド

GreetingController.java
@GetMapping("/greeting")
public String greetingForm(Model model) {
  model.addAttribute("greeting", new Greeting());
  return "greeting";
}

1.@GetMapping
このアノテーションを付与する事で、()内に記述したURLでGETリクエストがあった時に付与されたメソッドが呼び出されるようになります。
今回は@GetMapping("/greeting")です。したがって、http://localhost8080/greetingでGETリクエストがあった時、greetingFormメソッドが呼ばれます。

2.model.addAttribute
メソッドの引数にModelクラスの引数を受け取っています。これは、View側に渡すデータを設定するためです。
addAttribute(第一引数、第二引数)メソッドを用いる事でView側にデータを渡しており、
第二引数にデータを設定して、第一引数の名前でView側でそのデータを使用することが出来ます。

今回は、インスタンス化されたGreetingオブジェクトgreetingという名前でViewに渡しています。
Greetingの実装は後ほど。

3.メソッドの戻り値
メソッドの戻り値にViewを指定しています。今回はgreetingをreturnしています。
という事は、greeting.htmlが必要であるという事になります。実装は後ほど。

②greetingSubmitメソッド

GreetingController.java
@PostMapping("/greeting")
public String greetingSubmit(@ModelAttribute Greeting greeting) {
  return "result";
}

1.@PostMapping
このアノテーションを付与する事で、()内に記述したURLでPOSTリクエストがあった時に付与されたメソッドが呼び出されるようになります。
今回は@PostMapping("/greeting")です。したがって、http://localhost8080/greetingでPOSTリクエストがあった時、greetingSubmitメソッドが呼ばれます。

2.@ModelAttribute
メソッドの引数にあるこのアノテーションは、指定したクラスにPOSTで送られてきた値をセットするためのものです。
今回は、greeting変数に送られてきた値が格納されており、Greetingクラスの各変数に値がセットされます。

3.メソッドの戻り値
メソッドの戻り値にViewを指定しています。今回はresultをreturnしています。
という事は、result.htmlが必要であるという事になります。実装は後ほど。

Greeting.javaを作成しよう!

src/main/java/com/example/handlingformsubmission/ にGreeting.javaファイルを作成します。

スクリーンショット 2020-07-08 13.23.40.png

公式を参考にコードを追加します。

Greeting.java
package com.example.handlingformsubmission;

public class Greeting {

  private long id;
  private String content;

  public long getId() {
    return id;
  }
  public void setId(long id) {
    this.id = id;
  }

  public String getContent() {
    return content;
  }
  public void setContent(String content) {
    this.content = content;
  }

}

追加したコードを深掘りしていきます。

1.変数の宣言

Greeting.java
private long id;
private String content;

long型のidString型のcontentと2つの変数を宣言しています。
アクセス修飾子はprivateなので同一クラス内からしかアクセス出来ません。

2.ゲッター、セッターメソッドの定義

Greeting.java
public long getId() {
  return id;
}
public void setId(long id) {
  this.id = id;
}

public String getContent() {
  return content;
}
public void setContent(String content) {
  this.content = content;
}

formで送信された値を格納したり、取り出したりするためのゲッター、セッターメソッドを用意します。

greeting.htmlを作成しよう!

src/main/resources/templates/ にgreeting.htmlファイルを作成します。
このhtmlファイルはフォーム画面を表示するためのものです。

スクリーンショット 2020-07-08 13.52.37.png

公式を参考にコードを追加します。

greeting.html
<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
    <title>Getting Started: Handling Form Submission</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <h1>Form</h1>
    <form action="#" th:action="@{/greeting}" th:object="${greeting}" method="post">
      <p>Id: <input type="text" th:field="*{id}" /></p>
      <p>Message: <input type="text" th:field="*{content}" /></p>
      <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
    </form>
</body>
</html>

追加したコードのthymeleafの記述について深掘りしていきます。

thymeleafとは、springbootで扱う事が出来るテンプレートエンジンです。th:〇〇と記述します。
日本語で書かれたthymeleafチュートリアルもあります!

th:action

formタグのaction属性の内容を置換しています。記述の仕方は、th:action="@{}"です。
method="post"となっているので、Submitボタンが押された時にGreetingControllerのgreetingSubmitメソッドが呼ばれます。

th:object

th:objectでオブジェクトを指定しています。これにより、オブジェクト内の変数の参照の仕方がgreeting.idではなく、*{id}のような記述方法が可能になります。

th:field

th:objectで指定したオブジェクト内の変数を表示するためにth:field="*{変数名}"と記述します。
今回は、Greetingクラスの中にid、contentがあるので、th:field="*{id}"th:field="*{content}"となります。
また、th:field="*{変数名}"の中に記述した変数名がinputのid属性とname属性になります。

result.htmlを作成しよう!

src/main/resources/templates/ にresult.htmlファイルを作成します。
このhtmlファイルはフォーム画面から送られた結果を表示するためのものです。

スクリーンショット 2020-07-08 14.57.32.png

公式を参考にコードを追加します。

result.html
<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
    <title>Getting Started: Handling Form Submission</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <h1>Result</h1>
    <p th:text="'id: ' + ${greeting.id}" />
    <p th:text="'content: ' + ${greeting.content}" />
    <a href="/greeting">Submit another message</a>
</body>
</html>

追加したコードのthymeleafの記述について深掘りしていきます。

th:text

th:text="{変数名}"とする事で変数をテキストとして表示する事が出来ます。
文字列も混ぜて表示する際は、''で文字列を囲い、で連結させる事で文字列と変数を結合して表示出来ます。

今回は、フォームで送られてきたGreetingクラスのidとcontentを表示しているので、
th:text="'id: ' + ${greeting.id}"th:text="'content: ' + ${greeting.content}"となります。

3.実行してみよう!

アプリケーション実行の準備が出来たので確認しましょう。

ターミナルで以下のコマンドを入力してEnterしてください。

ターミナル
$ ./mvnw spring-boot:run

そして、http://localhost:8080/greetingにアクセスすると以下のフォーム画面が表示されるはずです。(greeting.htmlが表示される)

スクリーンショット 2020-07-08 15.23.43.png

IdとMessageに任意の値を入力して、Submitボタンをクリックしてください。
そうするとResult画面が表示されるはずです。(result.htmlが表示される)

スクリーンショット 2020-07-08 15.25.36.png

完成です!お疲れ様でした。

参考サイト

@ModelAttribute を使う
Thymeleafの使い方
Spring Boot で Thymeleaf 使い方メモ

morioheisei
ふざけた名前ですが常に本気です。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away