Spring Boot入門:ThymeleafとController

Spring Boot入門Step1アイキャッチプログラム
スポンサーリンク

この記事では、Spring Bootでブラウザからの入力を受け取る方法と逆にブラウザに出力する方法を説明します。

どんな複雑なシステムでも、入力から始まって出力で終わります。まずは最初の一歩として簡単な入出力を勉強してみましょう。

この記事を読むとわかること
  • Spring Bootでブラウザから入力を受け取る方法
  • Spring Bootでブラウザに動的な出力を行う方法
  • Spring Bootのコントローラ(Controller)の初歩
  • テンプレートエンジンThymeleafの初歩
前提条件
  • Spring Bootの開発環境が整っている
  • 解説ではPleiades All in One Eclipseを使う
  • Javaのバージョンは11
  • Spring Bootのバージョンは2.5.4

まだ開発環境が整っていない場合、次の記事を参考にしてください。

この記事のソースコード

1から順番に説明していくので、できれば理解しながら自分の手で書いてもらいたいです。しかし、面倒な方のために完成品のソースコードも用意しました。Githubに公開してありますので、利用してください。

GitHub - gsg0222/spring-boot-tutorial-step1
Contribute to gsg0222/spring-boot-tutorial-step1 development by creating an account on GitHub.

Pleiades All in One Eclipse(普通のEclipseでもほぼ同じ)でソースコードをインポートする方法は、次の記事で説明しています。

Spring Bootプロジェクト作成

まずは今回の説明に使うSpring Bootプロジェクトを作成します。[ファイル(F)]→[新規(N)]→[Springスターター・プロジェクト]と選んでください。

Springスタータープロジェクトを選択

新規Springスタータープロジェクトウインドでは、下の画像の通りに入力します。もちろん適当に変更しても大丈夫です。ただ、赤線で囲った範囲は指定した通りにしないと予想外のエラーが出たりする可能性があります。

Springスタータープロジェクト初期設定その1

次へを押して依存関係の設定を行います。今回はLombok、Spring Web、Thymeleafが必要です。

Springスタータープロジェクト初期設定その2、依存関係

完了を押せばプロジェクトが作成されます。必要なライブラリのダウンロードを行うので、しばらく待機が必要です。

Lombokってなんだ?

依存関係の設定のところで、サラッとLombokという単語が出てきました。このライブラリを使うと、ボイラープレートコード(単純で決まりきった記述)をアノテーションで代用できます。

例えばSetterとGetterなどは決まりきった内容になりがちです。Lombokを使うと@Setter、@Getterというアノテーションだけで済むようになります。

必要に応じて説明していきますので、今は便利なライブラリがあることだけを覚えて貰えれば大丈夫です。

なお、Pleiades All in One Eclipseを使っていない場合はインストールが必要になるかもしれません。EclipseにLombokを設定する方法などをみて適宜対応してください。

準備ができたところでいよいよコーディングに入ります。

データ入力用HTMLを出力するController

Spring BootではどのURLにアクセスされたらどんな処理を行うのかをControllerクラスで行います

先程新規Springスタータープロジェクトウインドで設定したパッケージより下の階層に@Controllerアノテーションを付けたクラスを作ると、それがControllerクラスです。

ここで作るのは、/inputにアクセスされたらHTMLを出力するだけの最も簡単なものになります。

パッケージエクスプローラーのblog.tsuchiya.tutorial.step1を右クリックして、[新規(N)]→[クラス]を選択するとクラス作成ウインドウが表示されます。

クラスの新規追加

パッケージをblog.tsuchiya.tutorial.step1.controller、名前をInputControllerとして新規にクラスを作りましょう。

新規クラス情報入力

クラスの中身は以下のように編集します。

package blog.tsuchiya.tutorial.step1.controller;

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

// 最需要アノテーション。このクラスがControllerであることを宣言する。
@Controller
public class InputController {

	// どのURLにアクセスしたらこのメソッドが呼ばれるか宣言する
	@GetMapping("input")
	// メソッド名は何でもいい
	public String input() {
		// 戻り値はThymeleafテンプレートの位置
		// src/main/resources/templatesからのパスを書く
		// 拡張子は省略する
		return "input";
	}
}

大体コメントの通りです。本当に最小限なのであまり説明するところはありません。

inputメソッドの戻り値だけ少し説明します。コメントに書いてあるとおり、このメソッドを呼ばれた際に表示したいThymeleafテンプレートの位置を、拡張子を省略した形で返します。

この場合は/indexにブラウザからアクセスされると、「src/main/resources/templates/input.html」が表示されるということです。

データ入力用HTMLのためのThymeleafテンプレート

「src/main/resources/templates/input.html」にデータ入力用のhtmlを作成します。

Controllerのコメントでもちょっと説明しましたが、Thymeleafテンプレートは「 src/main/resources/templates/ 」に保存するのがSpring Bootでのルールです。

Thymeleafテンプレートは普通のHTMLを拡張する形で実装します。htmlタグに「xmlns:th=”http://www.thymeleaf.org”」属性を追加するとThymeleafを利用可能です。

データ入力用HTMLでは、フォームからの入力を行うだけなのでThymeleaf要素はほとんどありません。

<!DOCTYPE html>
<!--/* Thymeleafを使うことを宣言。 */-->
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<!--/* Bootstrapを使う。本質とは関係ないのであんまり気にしなくていい。 */-->
<link
	href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css"
	rel="stylesheet">
<title>入力</title>
</head>
<body>
	<main class="container">
		<h1>値を入力してください</h1>
		<!--/* Thymeleafの属性を使用。ただのaction、methodでも動く。 */-->
		<form th:action="@{/output}" th:method="post">
			<div class="mb-3">
				<label for="text1" class="form-label">入力その1</label> <input
					type="text" class="form-control" id="text1" name="text1">
			</div>
			<div class="mb-3">
				<label for="text2" class="form-label">入力その1</label> <input
					type="text" class="form-control" id="text2" name="text2">
			</div>
			<div class="mb-3">
				<label for="text3" class="form-label">入力その1</label> <input
					type="text" class="form-control" id="text3" name="text3">
			</div>
			<button type="submit" class="btn btn-primary">入力完了</button>
		</form>
	</main>
</body>
</html>

テキスト項目を3つ持つ入力フォームを表示するだけの内容です。一応formタグにThymeleafの属性を使って見ましたが、この内容だと別に使わなくても問題ないです。

ちなみに、Thymeleafのコメントは<!–/* コメント */–>と書きます。「/」と「-」の間にスペースがあってはいけません。スペースがあるとThymeleafのコメントではなくHTMLのコメントになってしまいます。どちらでもブラウザの表示では差は出ないのですが、スペースがあるとブラウザで[ページのソースを表示]するときにコメントが残ります。

データを受け取るController

データを受け取るControllerを実装していきます。

入力を受け取るクラス

先に、フォームからのデータを受け取るクラスを定義してしまいましょう。2つのフィールドを持つ単純なクラスです。

InputControllerと同じようにクラスを作成します。パッケージはblog.tsuchiya.tutorial.step1.controller.formでクラス名はInputFormです。

package blog.tsuchiya.tutorial.step1.controller.form;

import lombok.Data;

// SetterとGetter、toString、equals、hashCodeを
// 生成するアノテーション
@Data
public class InputForm {

	private String text2;
	
	private String text3;
}

普通にGetterとSetterを手で書いてもいいのですが、せっかくなのでLombokのアノテーションを利用しました。

@Dataアノテーションは、コメントに書いたとおりGetterやSetterなどを自動的に作成してくれます。

メソッドが自動生成される

単純作業をアノテーションが肩代わりしてくれました。

入力を受け取るController

そして本体であるControllerクラスです。パッケージはblog.tsuchiya.tutorial.step1.controller、クラス名はOutputControllerとします。

package blog.tsuchiya.tutorial.step1.controller;

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

import blog.tsuchiya.tutorial.step1.controller.form.InputForm;

@Controller
public class OutputController {

	// postメソッドのときに呼ばれることを宣言。
	// getでこのURLが指定されたら405エラー。
	@PostMapping("output")
	// 2つの方法で入力Formから値を取得している。
	// @RequestParamを使うと、特定の1つの値を取得できる。
	// クラスを使うとまとめて複数の値を取得できる。
	public String output(@RequestParam(required = false) String text1, InputForm inputForm, Model model) {
		// Modelに値を格納してThymeleafに渡す。
		model.addAttribute("output1", text1);
		model.addAttribute("output2", inputForm);
		return "output";
	}
}

input.htmlでは/outputに対してpostメソッドでtext1、text2、text3という3つの文字列を渡します。それらの値を受け取るのがOutputControllerのoutputメソッドです。

入力の受け取り方

Spring Bootでは、@GetMappingや@PostMappingアノテーションを付けたメソッドの引数に自動的に入力フォームからの値を紐付けてくれます。

方法は2つ。

  1. @RequestParamを使う
  2. Setterを定義したクラスを引数にする

どちらでも良いのですが、大抵は2の方法が使われます。フォームから渡される値の数が1つということはないので、まとめて受け取れるほうが楽だからです。

1の@RequestParamを使うやり方は、引数にこのアノテーションを付けるだけです。引数の名前とおなじフォームからの入力が紐付きます。今回のケースでは、input.htmlのname=”text1″だったinputタグの値が引数text1に格納されるわけです。

なお、required = falseの意味は別に必須ではないよ、ということ。もしtext1が入力フォームから渡されなかった場合text1引数にはnullが入ります。

2はフォームからの入力と同じ名前を持つフィールドに紐付きます。input.htmlのtext2とtext3がinputFormのtext2、text3に格納されます。

こちらでも、入力フォームからtext2、text3が渡されなかった場合inputFormのtext2とtext3はnullです。

Thymeleafへ値を渡す方法

入力された値をThymeleafで表示するためには、値をThymeleafに渡さなくてはなりません。

@GetMapping、@PostMappingをつけたメソッドの引数Modelには、Spring Bootが自動的にModelのインスタンスを渡してくれます。このModelインスタンスに値を渡すと、Thymeleafで受け取ることが可能です。

実際のコードはこの部分になります。

		model.addAttribute("output1", text1);
		model.addAttribute("output2", inputForm);

text1の値をoutput1という名前でThymeleafに渡し、inputFormの値をoutput2という名前で渡します。

addAttributeメソッドの第二引数はObject型なので、どんな値でもThymeleafに渡すことが可能です。

データ出力先Thymeleafテンプレート

「src/main/resources/templates/output.html」にデータ出力用のhtmlを作成します。

input.htmlに比べると、少しだけThymeleafっぽい処理が増えました。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<link
	href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css"
	rel="stylesheet">
<title>出力</title>
</head>
<body>
	<main class="container">
		<h1>フォームへの入力を出力します</h1>
		<p class="text-primary" th:text="${output1}">出力1</p>
		<p class="text-secondary" th:text="${output2.text2}">出力2</p>
		<p class="text-success" th:text="${output2.text3}">出力3</p>
	</main>
</body>
</html>

th:text=”${output1}”の部分で、output1に渡した値をテキストとして表示するという指示になります。この属性を付けたタグのテキスト部分がoutput1に渡した値に変わるわけです。

th:text属性を付けたすべてのpタグには既にテキストが書かれていますが、Spring Bootからoutput.htmlを出力する際は無視されてth:text属性で指定された値に置き換わります。

output2にはSetterとGetterを定義したクラスのインスタンスを渡しました。この場合、それぞれのフィールドの値を表示する場合はth:textに${output2.text3}の様な形で指定します。

{modelに渡した名前}.{フィールド名}

こうすると、Thymeleafが自動的に「getフィールド名」メソッドを内部的に呼び出してくれるのです。

実際に動かしてみる

ソースコードを書き終わったので、実際に動かしてみます。プロジェクトエクスプローラーからstep1を右クリックして[実行(R)]→[9 Spring Boot App]をクリックしてみましょう。

Spring Bootアプリの実行

しばらくすると左下のコンソールにログが流れ、Spring Bootアプリが起動します。

http://localhost:8080/inputにアクセスすると入力ページが表示されるはず。

入力ページ

各入力項目に適当な文字を打ち込んで、[入力完了]を押してください。そうすると出力ページに入力した文字が表示されます。

出力ページ

とりあえず動くことが確認できたら、自分で少し修正して見ることをおすすめします。

  • URLを変えてみる
  • 入力項目の名前を変更する
  • 入力項目を増やす

などなど、今回説明した内容が理解できていたら色々試せることがあるでしょう。

まとめ

Spring Bootの基本であるControllerとThymeleafの説明をしてきました。

入力と出力はすべてのアプリケーションの基本です。まずはしっかり理解しましょう。

もしどこかでエラーが発生したら、Githubのコードと見比べて確認すると解決できるかと思います。もし原因がさっぱりわからないようでしたら、Twitterお問い合わせフォームで質問してください。可能な限りお答えしますし、この記事もアップデートしていく予定です。

Spring Boot入門:Thymeleafの基本に続きます。

おすすめ

せっかくJavaを勉強しているのなら、資格を取得してみませんか?OCJP(Oracle Certified Java Programmer) SilverはJavaの基本を学ぶのに適した資格です。初心者はもとより、中堅の人でも普段使わない機能を勉強するきっかけになると思います。

残念なことに試験は有料で、しかも結構高い(税抜26,600円)です。

しかし、お勤めの会社によっては費用を負担してくれるところもあるでしょうし、場合によっては報奨金まで出してくれるはずです。(私の会社は初回の試験料負担+報奨金を出してくれました)

私のおすすめな勉強方法は徹底攻略Java SE 11 Silver問題集を読むことです。問題集ですが、解説が充実しています。

徹底攻略Java SE 11 Silver問題集[1Z0-815]対応 徹底攻略シリーズ | 志賀 澄人 | 工学 | Kindleストア | Amazon
Amazonで志賀 澄人の徹底攻略Java SE 11 Silver問題集[1Z0-815]対応 徹底攻略シリーズ。アマゾンならポイント還元本が多数。一度購入いただいた電子書籍は、KindleおよびFire端末、スマートフォンやタブレットなど、様々な端末でもお楽しみいただけます。

大体30時間くらいの勉強で合格できました。

コメント

タイトルとURLをコピーしました