Spring Bootを使った新人エンジニア向けWebアプリ開発テキスト
第1章:Spring Bootの概要
1.1 Spring Bootとは?
Spring Boot は、Java を使った Web アプリケーション開発を簡単にするフレームワークです。
Spring フレームワークをベースにしており、設定の手間を減らし、シンプルに開発できるのが特徴です。
主な特徴
- 設定不要で使える:自動設定(Auto Configuration)により、設定ファイルの記述を最小限にできる。
- 組み込みサーバ:Tomcat などのサーバが最初から組み込まれており、単体で動作可能。
- 依存関係の管理が簡単:Maven で必要なライブラリを簡単に追加できる。
- 軽量な開発環境:Spring Boot DevTools を使うと、変更を即時反映できる。
1.2 依存関係の確認とプロジェクト構成
Spring Boot のプロジェクトでは、Maven を使って必要なライブラリを管理します。
今回のプロジェクトでは、以下の依存関係を使用します。
<dependencies>
<!-- Webアプリに必要 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Thymeleafテンプレートエンジン -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Spring JDBC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- MySQLドライバ -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
プロジェクト構成
SpringBootSample/
├── src/main/java/com/example/demo/
│ ├── SpringKaeruApplication.java # 起動クラス
│ ├── controller/ # コントローラ層
│ │ ├── CarController.java
│ ├── model/ # データベースアクセス層
│ │ ├── Car.java
│ │ ├── CarDao.java
│ ├── service/ # ビジネスロジック層(今回はなし)
├── src/main/resources/
│ ├── application.properties # 設定ファイル
│ ├── templates/ # Thymeleafテンプレート
│ │ ├── kaeru.html
├── pom.xml # 依存関係を管理するファイル
1.3 EclipseでのSpring Bootプロジェクト作成
Spring Boot のプロジェクトを作成し、実際に起動してみましょう。
(1) Eclipseでプロジェクトを作成
- Eclipse を開き、「ファイル」→「新規」→「Spring Bootプロジェクト」を選択
- 「Spring Boot バージョン」は
3.1.1
を選択 - 「依存関係の追加」で以下を選択
- Spring Web
- Thymeleaf
- Spring Data JDBC
- MySQL Driver
- 「完了」をクリックしてプロジェクトを作成
(2) プロジェクトの起動
Eclipse の「SpringBootSampleApplication.java」を開き、main
メソッドを実行します。
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 新入社員のみなさんへ
*
* このクラスは、Spring Bootアプリケーションのエントリーポイント(起動クラス)になります。
*
* 【ポイント】 1. @SpringBootApplication - Spring Bootにおけるアプリケーションの自動設定(Auto
* Configuration)を有効にするアノテーションです。
*
* 2. mainメソッド - Javaの実行クラスはmainメソッドを持ちます。Spring Bootアプリケーションも同様にここが起点となり、
* アプリケーションを起動します。 - SpringApplication.run(SpringKaeruApplication.class, args)
* と呼び出すことで 内部的にTomcatなどのサーバが起動し、Webアプリケーションとして動作を開始します。
*
* 3. アプリケーション名 - クラス名「SpringKaeruApplication」という部分はプロジェクトごとに自由に設定できます。
* ただし、慣例として「(プロジェクト名)Application」という形式が多く使われます。
*
* 4. 基本の流れ - mainメソッドが呼び出される → SpringApplication.run(...) が実行される →
* Springフレームワークによる自動設定やコンポーネントの読み込み → アプリケーション起動
*
@SpringBootApplication
public class SpringKaeruApplication {
/**
* Javaプログラムの実行を開始するmainメソッドです。
* SpringApplication.run(...)によってSpringアプリケーションを起動します。
*
* @param args プログラム実行時に渡される引数(今回は特に使用しない想定)
*/
public static void main(String[] args) {
SpringApplication.run(SpringKaeruApplication.class, args);
}
}
ブラウザで http://localhost:8080
にアクセスすると、アプリケーションが起動していることを確認できます。
ハンズオン:Spring Bootの初期プロジェクトを作成し、起動してみよう
【目標】
Spring Boot のプロジェクトを作成し、ブラウザで起動を確認する。
【手順】
- Eclipse で Spring Boot プロジェクトを作成する。
SpringKaeruApplication.java
を実行し、アプリを起動する。http://localhost:8080
にアクセスし、エラーページが表示されることを確認する。
→ まだコントローラを作成していないため、エラーになるのが正しい動作です!
【確認ポイント】
- Eclipse で Spring Boot プロジェクトが作成できたか?
main
メソッドを実行し、Spring Boot アプリが起動したか?http://localhost:8080
にアクセスし、エラーが表示されたか?
まとめ
- Spring Boot は Java の Web アプリ開発を簡単にするフレームワーク。
- 設定の手間が少なく、最小限のコードで動作する。
- Eclipse で Spring Boot プロジェクトを作成し、実際に起動してみる。
次章では、Spring Boot の基本的な仕組みを理解し、簡単な Web ページを表示する方法を学びます!
第2章:Spring Bootの基本
2.1 Spring Bootのアノテーション
Spring Boot では、コードをシンプルにするために アノテーション を多用します。
本章では、Spring Boot の基本的なアノテーションを理解し、簡単な Web ページを表示する方法を学びます。
(1) @SpringBootApplication
Spring Boot アプリケーションの起動クラスに付けるアノテーションです。
このアノテーションをつけることで、Spring Bootの自動設定 (Auto Configuration) やコンポーネントスキャンが有効になります。
@SpringBootApplication
public class SpringKaeruApplication {
public static void main(String[] args) {
SpringApplication.run(SpringKaeruApplication.class, args);
}
}
@SpringBootApplication の内部の動作
- @Configuration: 設定クラスとして認識される
- @EnableAutoConfiguration: 自動設定を有効にする
- @ComponentScan: 指定したパッケージ以下のクラスを自動的に登録する
(2) @Controller
コントローラ (Controller) を表すアノテーションです。
このクラスは、ブラウザからのリクエストを受け取り、適切な処理を実行して画面にデータを渡す役割 を持ちます。
// コントローラーとして動作することを示すアノテーション
@Controller
public class HelloController {
// HTTPのGETリクエストで「/hello」にアクセスしたときに、このメソッドが呼び出される
@GetMapping("/hello")
public String hello() {
// 「hello」というビュー名を返す
// src/main/resources/templates/hello.html を表示する仕組み
return "hello";
}
}
@GetMapping("/hello")
によって、http://localhost:8080/hello
にアクセスするとhello.html
を表示する。
(3) @GetMapping
@GetMapping
は、HTTPのGETリクエストを受け付けるメソッド を定義するアノテーションです。
例えば、以下のように使います。
@Controller
public class HelloController {
// HTTP GETリクエストのマッピングを指定するアノテーション
// "/" へアクセスがあった場合にこのメソッドが呼び出される
@GetMapping("/")
public String index() {
// "index" という文字列を返すことで、
// src/main/resources/templates/index.html のテンプレートを表示する
return "index";
}
}
@GetMapping("/")
は、ブラウザからの「/」リクエスト (http://localhost:8080/) を処理 します。
2.2 アプリケーションの起動と開発環境の確認
Spring Boot の開発環境が正しく動作しているか確認します。
- Eclipse で
SpringKaeruApplication.java
を実行する http://localhost:8080/hello
にアクセスし、「エラーページ」が表示されることを確認する- エラーページになるのが正しい動作!
hello.html
をまだ作成していないため、テンプレートが見つからないエラーが出る
2.3 application.properties の基本設定
プロパティとは、アプリケーションの設定情報を管理する仕組みです。Spring Boot では、src/main/resources/application.properties
に設定を書いて、アプリの挙動を変更できます。
(1) ポート番号の変更
デフォルトでは 8080
ですが、変更したい場合は以下を追加します。
server.port=8081
これで、http://localhost:8081/
にアクセスするとアプリが動作します。
(2) Thymeleaf のキャッシュ無効化
Thymeleaf のテンプレートを編集するたびに、アプリを再起動しなくても変更を反映する設定です。ただし、Javaコードの変更には影響せず、Javaを修正した場合は アプリケーションの再起動が必要になります。開発環境では有効にしておくと効率が上がりますが、本番環境ではパフォーマンスのために true にしておくのが一般的です。
spring.thymeleaf.cache=false
2.4 簡単なWebページを表示する
Spring Boot を使って、簡単な Web ページを表示してみます。
(1) コントローラを作成
src/main/java/com/example/demo/controller/HelloController.java
を作成し、以下のコードを記述します。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "hello"; // hello.html を表示
}
}
(2) Thymeleaf のテンプレートを作成
src/main/resources/templates/hello.html
を作成し、以下の内容を記述します。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<!--
xmlns:th="http://www.thymeleaf.org" は、Thymeleafテンプレートエンジンの名前空間を指定しています。
このあとでThymeleafの `th:*` 属性(例: th:text, th:if など)を使用できるようになることを学びます。
-->
<head>
<meta charset="UTF-8">
<title>Hello Spring Boot</title>
</head>
<body>
<h1>Hello, Spring Boot!</h1>
</body>
</html>
(3) アプリを起動し、ブラウザで確認
SpringKaeruApplication.java
を実行するhttp://localhost:8080/hello
にアクセス- 「Hello, Spring Boot!」と表示されることを確認する
ハンズオン:シンプルなHello Worldアプリを作成する
【目標】
Spring Boot を使って、「Hello, Spring Boot!」を表示するWebアプリを作成する。
【手順】
HelloController.java
を作成hello.html
を作成- アプリを起動し、ブラウザで動作確認
http://localhost:8080/hello
にアクセス- 「Hello, Spring Boot!」が表示されることを確認
まとめ
- @SpringBootApplication はSpring Bootの基本設定をまとめたアノテーション
- @Controller はWebリクエストを処理するクラス
- @GetMapping でURLと処理を紐づける
- Thymeleaf を使って簡単なWebページを作成
- application.properties でアプリの設定を変更できる
次章では、Thymeleaf の基本を学び、動的なデータを表示する方法を学習します!
第3章:Thymeleafによる画面表示
3.1 Thymeleafとは?
Thymeleaf(タイムリーフ)は、Spring Boot の公式テンプレートエンジンです。
HTMLファイルの中に動的なデータを埋め込むことができ、JavaとHTMLを直感的に組み合わせられるのが特徴です。
Thymeleafの特徴
- 通常のHTMLとして表示可能(開発中でもブラウザで確認しやすい)
- Spring Bootと統合が簡単(特別な設定なしで使用できる)
- シンプルな構文でJavaオブジェクトを埋め込める
- セキュリティ対策がデフォルトで有効(XSS対策など)
3.2 HTMLテンプレートの作成
Spring Boot のテンプレートは src/main/resources/templates/
に配置します。
まず、以下のようなシンプルなHTMLを作成します。
(1) テンプレートの作成
src/main/resources/templates/welcome.html
を作成し、以下のコードを記述します。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Welcome</title>
</head>
<body>
<h1 th:text="${message}">Hello, Thymeleaf!</h1>
</body>
</html>
(2) コントローラの作成
src/main/java/com/example/demo/controller/WelcomeController.java
を作成し、以下のコードを記述します。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class WelcomeController {
@GetMapping("/welcome")
public String welcome(Model model) {
model.addAttribute("message", "Spring Bootへようこそ!");
return "welcome"; // welcome.html を表示
}
}
3.3 Thymeleafの基本構文
Thymeleaf では、HTML内で th:*
という特別な属性を使って動的なデータを埋め込むことができます。
構文 | 例 | 説明 |
---|---|---|
th:text | <p th:text="${message}"> | テキストを埋め込む |
th:if / th:unless | <p th:if="${isLoggedIn}"> | 条件分岐 |
th:each | <li th:each="item : ${items}"> | ループ処理 |
th:href | <a th:href="@{/home}">Home</a> | リンクの生成 |
th:action | <form th:action="@{/submit}"> | フォームの送信先 |
th:value | <input th:value="${username}"> | 入力値の設定 |
3.4 ループ処理(一覧表示)
データのリストを表示する場合、th:each
を使います。
(1) コントローラでデータを準備
src/main/java/com/example/demo/controller/ProductController.java
を作成します。
package com.example.demo.controller;
import java.util.Arrays;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class ProductController {
@GetMapping("/products")
public String products(Model model) {
// 商品リストを作成(固定のデータを用意)
List<String> productList = Arrays.asList("車A", "車B", "車C");
// Modelオブジェクトを使ってデータをView(HTML)に渡す
// "products" というキーで productList を Thymeleaf などのテンプレートエンジンに提供
return "products"; // products.html を表示
}
}
(2) Thymeleafでリストを表示
src/main/resources/templates/products.html
を作成し、以下のコードを記述します。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>商品一覧</title>
</head>
<body>
<h1>商品一覧</h1>
<ul>
<!--
th:each="product : ${products}" の解説:
- "products" はコントローラー側でModelに追加されたリスト。
- "th:each" は Thymeleaf の繰り返し処理を行う属性。
- "product" という変数に、リスト "products" の各要素が順番に入る。
- リストの要素数だけ <li> 要素が生成される。
-->
<!--
th:text="${product}" の解説:
- "${product}" は、th:each でセットされた各要素。
- <li> 内のテキストがリストの各アイテムに置き換えられる。
- 例えば、"車A", "車B", "車C" が products に含まれている場合、
それぞれの <li> 要素に "車A", "車B", "車C" が表示される。
-->
<li th:each="product : ${products}" th:text="${product}">商品名</li>
</ul>
</body>
</html>
ブラウザで http://localhost:8080/products
にアクセスすると、以下のように表示されます。
商品一覧
- 車A
- 車B
- 車C
3.5 条件分岐
Thymeleafでは、th:if
や th:unless
を使って条件分岐ができます。
(1) コントローラの作成
src/main/java/com/example/demo/controller/DiscountController.java
を作成します。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class DiscountController {
@GetMapping("/discount")
public String discount(Model model) {
model.addAttribute("isDiscount", true);
return "discount";
}
}
(2) Thymeleafで条件分岐
src/main/resources/templates/discount.html
を作成し、以下のコードを記述します。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>セール情報</title>
</head>
<body>
<h1>セール情報</h1>
<!--
th:if は、Thymeleaf の条件分岐を行う属性。
${isDiscount} の値が true(または null 以外の値)ならば、この <p> 要素が表示される。
例えば、Controller で model.addAttribute("isDiscount", true) と設定すると、
「今だけ特別割引中!」というテキストが表示される。
-->
<p th:if="${isDiscount}">今だけ特別割引中!</p>
<!--
th:unless は th:if の逆の意味を持ち、${isDiscount} の値が false(または null)ならば、この <p> 要素が表示される。
例えば、Controller で model.addAttribute("isDiscount", false) または値を設定しない場合、
「現在セールは行っていません。」が表示される。
-->
<p th:unless="${isDiscount}">現在セールは行っていません。</p>
</body>
</html>
ブラウザで http://localhost:8080/discount
にアクセスすると、以下のように表示されます。
セール情報
今だけ特別割引中!
3.6 ユーザー入力の受け取り
Spring Boot + Thymeleaf では、フォームを使ってユーザー入力を受け取ることもできます。
(1) フォームを表示
src/main/resources/templates/input.html
を作成します。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>ユーザー入力</title>
</head>
<body>
<h1>名前を入力してください</h1>
<form th:action="@{/greet}" method="get">
<!--
th:action は Thymeleaf の属性で、フォームの送信先 URL を指定します。
"@{/greet}" は Spring Boot のコントローラのエンドポイント "/greet" にマッピングされます。
例えば、`@GetMapping("/greet")` のようなメソッドが Spring のコントローラに定義されていれば、
フォームを送信した際に、そのメソッドが処理を行います。
-->
<input type="text" name="name">
<button type="submit">送信</button>
</form>
</body>
</html>
(2) 入力を処理
src/main/java/com/example/demo/controller/GreetController.java
を作成します。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class GreetController {
@GetMapping("/greet")
public String greet(@RequestParam String name, Model model) {
// クライアントからのリクエストパラメータ "name" を受け取る
// 例えば "/greet?name=Taro" のようなリクエストが来ると、name には "Taro" が格納される
model.addAttribute("name", name);
return "greet";
}
}
(3) 画面に表示
src/main/resources/templates/greet.html
を作成します。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>挨拶</title>
</head>
<body>
<h1>こんにちは、<span th:text="${name}">ゲスト</span>さん!</h1>
</body>
</html>
ハンズオン:Thymeleafを使って商品一覧を表示する
【目標】
Thymeleaf を使い、商品のリストを画面に表示する。
【手順】
- コントローラ (
ProductController.java
) を作成 - テンプレート (
products.html
) を作成 - ブラウザで
http://localhost:8080/products
にアクセスし、リストが表示されることを確認
まとめ
- Thymeleaf は Spring Boot の公式テンプレートエンジン
th:text
でテキストを埋め込めるth:each
でリストを表示できるth:if
で条件分岐ができる
次章では、コントローラの役割を深掘りしていきます!
第4章:Spring MVCの基本
4.1 Spring MVCとは?
Spring MVC は、Spring フレームワークの一部であり、Webアプリケーションの開発を簡単にするための仕組み です。
従来の Servlet + JSP に比べ、コードの記述量が少なく、整理されたアーキテクチャで開発できる のが特徴です。
Spring MVCの基本構造
Spring MVC では、以下の3つの要素を中心に構成されます。
- コントローラ (Controller)
- ブラウザからのリクエストを受け取り、適切な処理を行う
@Controller
を使って定義する
- モデル (Model)
- データを管理する
@Service
や@Repository
を使って定義する
- ビュー (View)
- 画面を表示する(Thymeleafなど)
src/main/resources/templates/
にHTMLを配置する
4.2 @Controllerと@GetMappingの使い方
コントローラを使ってWebページを制御します。
(1) @Controller の基本
@Controller
は、リクエストを受け取るクラスに付けます。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/") // http://localhost:8080/ にアクセスしたときの処理
public String index() {
return "index"; // index.html を表示
}
}
解説
@Controller
を付けることで、このクラスがWebリクエストを処理することを宣言。@GetMapping("/")
により、http://localhost:8080/
にアクセスするとindex.html
を表示。
4.3 Modelを使ってデータを画面に渡す
Model
を使ってコントローラから画面(HTML)にデータを渡します。
(1) コントローラでデータを渡す
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class GreetingController {
@GetMapping("/greeting")
public String greeting(Model model) {
model.addAttribute("name", "新入社員");
return "greeting"; // greeting.html を表示
}
}
(2) Thymeleafでデータを表示
src/main/resources/templates/greeting.html
を作成し、以下のコードを記述。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>挨拶</title>
</head>
<body>
<h1>こんにちは、<span th:text="${name}">ゲスト</span>さん!</h1>
</body>
</html>
結果
http://localhost:8080/greeting
にアクセスすると、
「こんにちは、新入社員さん!」 と表示される。
4.4 URLパラメータを受け取る
URLのパラメータを受け取ることも可能です。
(1) @RequestParam を使う
@RequestParam
を使うと、URLのパラメータを取得できます。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class WelcomeController {
@GetMapping("/welcome")
public String welcome(
// クエリパラメータ "name" を受け取るための @RequestParam アノテーション
@RequestParam(
name = "name", // クエリパラメータのキーを指定(例: /welcome?name=太郎)
required = false, // パラメータが省略されてもエラーにならないようにする
defaultValue = "ゲスト" // パラメータが渡されなかった場合のデフォルト値
) String name,
Model model // ビューにデータを渡すための Model オブジェクト
) {
model.addAttribute("name", name);
return "welcome";
}
}
(2) HTMLで表示
src/main/resources/templates/welcome.html
を作成。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Welcome</title>
</head>
<body>
<h1>ようこそ、<span th:text="${name}">ゲスト</span> さん!</h1>
</body>
</html>
動作確認
http://localhost:8080/welcome?name=田中
- 「ようこそ、田中さん!」 と表示される。
4.5 フォーム入力の受け取り
フォームを使ってデータを入力し、処理することができます。
(1) フォームを作成
src/main/resources/templates/form.html
を作成。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>入力フォーム</title>
</head>
<body>
<h1>名前を入力してください</h1>
<form th:action="@{/submit}" method="post">
<!-- th:action="@{/submit}" は、Thymeleaf の構文を使用してフォームの送信先 URL を指定します。
@{} の中にパスを書き、サーバー側のエンドポイント(/submit)にデータを送信します。
例えば、Spring Boot では @PostMapping("/submit") で処理することが一般的です。 -->
<!-- method="post" は、HTTP メソッドの指定です。
データを送信する際に GET ではなく POST を使用することで、
URL にデータを含めず、安全に送信できます。 -->
<input type="text" name="name">
<button type="submit">送信</button>
</form>
</body>
</html>
(2) コントローラでフォームのデータを受け取る
package com.example.demo.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;
@Controller
public class FormController {
@PostMapping("/submit")
public String submit(@RequestParam String name, Model model) {
model.addAttribute("name", name);
return "result";
}
}
(3) 結果を表示
src/main/resources/templates/result.html
を作成。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>結果</title>
</head>
<body>
<h1>こんにちは、<span th:text="${name}">ゲスト</span> さん!</h1>
</body>
</html>
動作確認
http://localhost:8080/form
にアクセス- 名前を入力して送信
result.html
に入力した名前が表示される
ハンズオン:コントローラを作成してデータを画面に表示する
【目標】
- コントローラからデータを Thymeleaf に渡して表示する。
【手順】
- コントローラ (
GreetingController.java
) を作成 - Thymeleaf (
greeting.html
) を作成 - ブラウザで
http://localhost:8080/greeting
にアクセス - 「こんにちは、新入社員さん!」と表示されることを確認
まとめ
- 「Controller → Model → View」 で構成される。
@Controller
を使うと、リクエストを処理できる。@GetMapping
でページを表示する。Model
を使ってコントローラからビューにデータを渡せる。@RequestParam
を使うと、URLのパラメータを受け取れる。- フォームを使うことで、ユーザー入力を受け取れる。
次章では、Spring Bootとデータベースを連携し、MySQLからデータを取得・表示する方法を学びます!
第5章:データベース接続 (JDBC)
5.1 Spring BootとMySQLの接続
Spring Bootでは、JDBCを使ってMySQLと簡単に連携できます。
本章では、Spring BootからMySQLのデータを取得し、画面に表示する方法 を学びます。
(1) MySQLの準備
すでにMySQLでデータベースとテーブルを作成済みですのでcarsテーブルを使っていきます。
(2) application.properties
の設定
Spring BootがMySQLと接続できるように、以下の設定を追加します。
src/main/resources/application.properties
# MySQL接続情報
spring.datasource.url=jdbc:mysql://localhost:3306/sip_a?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Tokyo
spring.datasource.username=newuser
spring.datasource.password=0
# JDBCドライバ
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# SQLログを出力
logging.level.org.springframework.jdbc.core=DEBUG
5.2 JDBCテンプレートの使い方
Spring Bootには JdbcTemplate
という便利なライブラリがあり、SQLをシンプルに記述できます。
(1) Carエンティティの作成
src/main/java/com/example/demo/model/Car.java
を作成し、以下のコードを記述します。
package com.example.demo.model;
import java.io.Serializable;
/**
* Carエンティティ
*/
public class Car implements Serializable {
private int carId;
private String name;
private int price;
/**
* 論理削除された日時 (nullの場合は未削除)
*/
private String deletedAt;
public Car() {
}
public Car(int carId, String name, int price, String deletedAt) {
this.carId = carId;
this.name = name;
this.price = price;
this.deletedAt = deletedAt;
}
public int getCarId() {
return carId;
}
public void setCarId(int carId) {
this.carId = carId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getDeletedAt() {
return deletedAt;
}
public void setDeletedAt(String deletedAt) {
this.deletedAt = deletedAt;
}
@Override
public String toString() {
return "Car{" + "carId=" + carId + ", name='" + name + '\'' + ", price=" + price + ", deletedAt='" + deletedAt
+ '\'' + '}';
}
}
(2) DAO(データアクセスオブジェクト)を作成
JdbcTemplate
を使って、データベースからデータを取得するDAOクラスを作成します。
src/main/java/com/example/demo/model/CarDao.java
package com.example.demo.model;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
/**
* Carテーブルへのアクセスを行うDAOクラス。 (Spring DataのCrudRepository等は使わず、JdbcTemplateで自前実装)
*/
@Repository
public class CarDao {
private final JdbcTemplate jdbcTemplate;
@Autowired
public CarDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
* 全件取得
*/
public List<Car> getCars() {
String sql = "SELECT * FROM cars";
List<Car> list = jdbcTemplate.query(sql, new RowMapper<Car>() {
@Override
public Car mapRow(ResultSet rs, int rowNum) throws SQLException {
Car c = new Car();
c.setCarId(rs.getInt("car_id"));
c.setName(rs.getString("name"));
c.setPrice(rs.getInt("price"));
c.setDeletedAt(rs.getString("deleted_at"));
return c;
}
});
return list;
}
//(中略)
5.3 データ取得の基本 (SELECT文)
Spring Bootのコントローラを作成し、データベースから取得したデータを画面に表示してみます。
(1) コントローラの作成
src/main/java/com/example/demo/controller/CarController.java
package com.example.demo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.example.demo.model.Car;
import com.example.demo.model.CarDao;
@Controller
public class CarController {
private final CarDao carDao;
@Autowired
public CarController(CarDao carDao) {
this.carDao = carDao;
}
@GetMapping("/cars")
public String listCars(Model model) {
List<Car> cars = carDao.getCars();
model.addAttribute("cars", cars);
return "car_list"; // car_list.html を表示
}
}
(2) Thymeleafでデータを表示
src/main/resources/templates/car_list.html
を作成します。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>車一覧</title>
</head>
<body>
<h1>車一覧</h1>
<table border="1">
<tr>
<th>ID</th>
<th>名前</th>
<th>価格</th>
</tr>
<tr th:each="car : ${cars}">
<td th:text="${car.carId}">1</td>
<td th:text="${car.name}">車の名前</td>
<td th:text="${car.price}">2000000</td>
</tr>
</table>
</body>
</html>
(3) アプリを実行して確認
SpringKaeruApplication.java
を起動するhttp://localhost:8080/cars
にアクセス- MySQLのデータが画面に表示されていれば成功!
ハンズオン:データベースから車一覧を取得し、画面に表示する
【目標】
Spring Boot を使い、MySQLのデータを画面に表示する。
【手順】
- データベース (MySQL) の作成
application.properties
にDB接続設定を追加- エンティティ (
Car.java
) を作成 - DAO (
CarDao.java
) を作成 - コントローラ (
CarController.java
) を作成 - ビュー (
car_list.html
) を作成 - ブラウザで
http://localhost:8080/cars
にアクセスし、データが表示されることを確認
まとめ
- Spring Boot では
JdbcTemplate
を使って MySQLと簡単に接続できる - DAOパターンを使って、データアクセスを分離する
- @Repository を使ってデータベースアクセスクラスを定義する
- @Autowired を使ってコンポーネントを自動的に注入できる
- Thymeleaf を使ってデータを動的に表示する
次章では、データの追加・更新・削除を行い、より本格的なデータ操作を学びます!
第6章:データの追加・更新・削除
6.1 データの追加(INSERT)
データベースに新しいデータを追加するには、SQLの INSERT
文を使います。
Spring Bootでは、JdbcTemplate
を使って簡単にデータを追加できます。
(1) フォームを作成
新しい車を登録するためのフォームを作成します。
src/main/resources/templates/car_form.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>車の追加</title>
</head>
<body>
<h1>新しい車を追加</h1>
<form th:action="@{/cars/add}" method="post">
<label>車の名前:</label>
<input type="text" name="name" required>
<br>
<label>価格:</label>
<input type="number" name="price" required>
<br>
<button type="submit">追加</button>
</form>
</body>
</html>
(2) コントローラの追加
フォームのデータを受け取って、データベースに登録します。
src/main/java/com/example/demo/controller/CarController.java
package com.example.demo.controller;
import com.example.demo.model.Car;
import com.example.demo.model.CarDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Controller
public class CarController {
private final CarDao carDao;
@Autowired
public CarController(CarDao carDao) {
this.carDao = carDao;
}
@GetMapping("/cars")
public String listCars(Model model) {
List<Car> cars = carDao.getCars();
model.addAttribute("cars", cars);
return "car_list"; // car_list.html を表示
}
@GetMapping("/cars/form")
public String carForm() {
return "car_form"; // car_form.html を表示
}
@PostMapping("/cars/add")
public String addCar(@RequestParam String name, @RequestParam int price) {
carDao.addCar(new Car(0, name, price));
return "redirect:/cars"; // 登録後に一覧ページへリダイレクト
}
}
(3) DAOにデータ追加メソッドを作成
JdbcTemplate
を使って INSERT
文を実行するメソッドを追加します。
src/main/java/com/example/demo/model/CarDao.java
public int addCar(Car car) {
String sql = "INSERT INTO cars (name, price) VALUES (?, ?)";
return jdbcTemplate.update(sql, car.getName(), car.getPrice());
}
(4) 確認
http://localhost:8080/cars/form
にアクセス- 車の名前と価格を入力して送信
http://localhost:8080/cars
でデータが追加されていることを確認
6.2 データの更新(UPDATE)
データを更新するには、SQLの UPDATE
文を使います。
(1) フォームの作成
編集用のフォームを作成します。
src/main/resources/templates/car_edit.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>車の編集</title>
</head>
<body>
<h1>車の編集</h1>
<form th:action="@{/cars/update}" method="post">
<input type="hidden" name="carId" th:value="${car.carId}">
<label>車の名前:</label>
<input type="text" name="name" th:value="${car.name}" required>
<br>
<label>価格:</label>
<input type="number" name="price" th:value="${car.price}" required>
<br>
<button type="submit">更新</button>
</form>
</body>
</html>
(2) コントローラの追加
更新処理のためのコントローラを追加します。
src/main/java/com/example/demo/controller/CarController.java
@GetMapping("/cars/edit")
public String editCar(@RequestParam int id, Model model) {
Car car = carDao.getCar(id);
model.addAttribute("car", car);
return "car_edit";
}
@PostMapping("/cars/update")
public String updateCar(@RequestParam int carId, @RequestParam String name, @RequestParam int price) {
carDao.updateCar(new Car(carId, name, price));
return "redirect:/cars";
}
(3) DAOに更新メソッドを追加
src/main/java/com/example/demo/model/CarDao.java
public int updateCar(Car car) {
String sql = "UPDATE cars SET name=?, price=? WHERE car_id=?";
return jdbcTemplate.update(sql, car.getName(), car.getPrice(), car.getCarId());
}
(4) 確認
http://localhost:8080/cars
で「編集」リンクをクリック- 車の情報を変更して送信
http://localhost:8080/cars
でデータが更新されたことを確認
6.3 データの削除(DELETE)
データを削除するには、SQLの DELETE
文を使います。
(1) 削除ボタンを追加
car_list.html
に削除ボタンを追加します。
src/main/resources/templates/car_list.html
<tr th:each="car : ${cars}">
<td th:text="${car.carId}"></td>
<td th:text="${car.name}"></td>
<td th:text="${car.price}"></td>
<td>
<a th:href="@{/cars/edit(id=${car.carId})}">編集</a>
<a th:href="@{/cars/delete(id=${car.carId})}" onclick="return confirm('削除しますか?')">削除</a>
</td>
</tr>
(2) コントローラの追加
削除処理のためのメソッドを追加します。
src/main/java/com/example/demo/controller/CarController.java
@GetMapping("/cars/delete")
public String deleteCar(@RequestParam int id) {
carDao.deleteCar(id);
return "redirect:/cars";
}
(3) DAOに削除メソッドを追加
src/main/java/com/example/demo/model/CarDao.java
public int deleteCar(int carId) {
String sql = "DELETE FROM cars WHERE car_id=?";
return jdbcTemplate.update(sql, carId);
}
(4) 確認
http://localhost:8080/cars
にアクセス- 「削除」ボタンをクリック
- データが削除されることを確認
ハンズオン:新しい車を追加・編集・削除できる機能を作成する
【目標】
Spring Boot を使い、MySQLのデータを追加・更新・削除できるようにする。
【手順】
- 追加フォーム (
car_form.html
) を作成 - 更新フォーム (
car_edit.html
) を作成 - 一覧ページ (
car_list.html
) に削除ボタンを追加 - DAO (
CarDao.java
) に追加・更新・削除メソッドを追加 - コントローラ (
CarController.java
) に追加・更新・削除処理を追加 - ブラウザで操作し、動作を確認
まとめ
INSERT
でデータを追加UPDATE
でデータを更新DELETE
でデータを削除JdbcTemplate
を使ってSQLを実行する
次章では、リクエストパラメータとフォーム入力を活用し、検索機能を実装します!
第7章:リクエストパラメータとフォーム入力
7.1 リクエストパラメータとは?
リクエストパラメータとは、URLやフォームを通じて送信されるデータ のことです。
Spring Bootでは、@RequestParam
を使って簡単に取得できます。
例: クエリパラメータ
http://localhost:8080/search?query=トヨタ
このURLでは、query
に "トヨタ"
という値が渡されています。
7.2 @RequestParam でパラメータを取得
@RequestParam
を使うと、URLからパラメータを取得できます。
(1) コントローラの作成
src/main/java/com/example/demo/controller/SearchController.java
package com.example.demo.controller;
import com.example.demo.model.Car;
import com.example.demo.model.CarDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Controller
public class SearchController {
private final CarDao carDao;
@Autowired
public SearchController(CarDao carDao) {
this.carDao = carDao;
}
@GetMapping("/search")
public String search(@RequestParam(name = "query", required = false) String query, Model model) {
List<Car> cars;
if (query == null || query.isEmpty()) {
cars = carDao.getCars(); // 何も入力されていない場合は全件取得
} else {
cars = carDao.searchCars(query);
}
model.addAttribute("cars", cars);
return "search_results"; // search_results.html を表示
}
}
(2) DAOに検索メソッドを追加
LIKE
を使った部分一致検索を行います。
src/main/java/com/example/demo/model/CarDao.java
public List<Car> searchCars(String keyword) {
String sql = "SELECT * FROM cars WHERE name LIKE ?";
String param = "%" + keyword + "%";
return jdbcTemplate.query(sql, new Object[]{param}, (rs, rowNum) ->
new Car(rs.getInt("car_id"), rs.getString("name"), rs.getInt("price"))
);
}
7.3 Thymeleafで検索フォームを作成
(1) 検索フォーム
src/main/resources/templates/search.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>検索</title>
</head>
<body>
<h1>車を検索</h1>
<form th:action="@{/search}" method="get">
<input type="text" name="query" placeholder="車の名前を入力">
<button type="submit">検索</button>
</form>
</body>
</html>
(2) 検索結果の表示
src/main/resources/templates/search_results.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>検索結果</title>
</head>
<body>
<h1>検索結果</h1>
<table border="1">
<tr>
<th>ID</th>
<th>名前</th>
<th>価格</th>
</tr>
<tr th:each="car : ${cars}">
<td th:text="${car.carId}"></td>
<td th:text="${car.name}"></td>
<td th:text="${car.price}"></td>
</tr>
</table>
</body>
</html>
(3) 動作確認
http://localhost:8080/search
にアクセス- 検索フォームに「トヨタ」と入力して送信
- 検索結果が一覧表示される
7.4 並べ替え機能を追加
検索結果を昇順・降順で並べ替えられるようにします。
(1) コントローラの修正
並べ替えのパラメータ (order
) を追加します。
@GetMapping("/search")
public String search(@RequestParam(name = "query", required = false) String query,
@RequestParam(name = "order", required = false, defaultValue = "asc") String order,
Model model) {
boolean isAscending = !order.equals("desc");
List<Car> cars;
if (query == null || query.isEmpty()) {
cars = carDao.getSortedCars("price", isAscending);
} else {
cars = carDao.searchAndSortCars(query, isAscending);
}
model.addAttribute("cars", cars);
model.addAttribute("query", query);
return "search_results";
}
(2) DAOの変更
新しい検索+並べ替えメソッドを追加。
public List<Car> getSortedCars(String sortField, boolean isAscending) {
String sortOrder = isAscending ? "ASC" : "DESC";
String sql = "SELECT * FROM cars ORDER BY " + sortField + " " + sortOrder;
return jdbcTemplate.query(sql, (rs, rowNum) ->
new Car(rs.getInt("car_id"), rs.getString("name"), rs.getInt("price"))
);
}
public List<Car> searchAndSortCars(String keyword, boolean isAscending) {
String sortOrder = isAscending ? "ASC" : "DESC";
String sql = "SELECT * FROM cars WHERE name LIKE ? ORDER BY price " + sortOrder;
String param = "%" + keyword + "%";
return jdbcTemplate.query(sql, new Object[]{param}, (rs, rowNum) ->
new Car(rs.getInt("car_id"), rs.getString("name"), rs.getInt("price"))
);
}
(3) 並べ替えボタンの追加
search_results.html
に並べ替えボタンを追加
<p>並べ替え:</p>
<form th:action="@{/search}" method="get">
<input type="hidden" name="query" th:value="${query}">
<button type="submit" name="order" value="asc">価格の昇順▲</button>
<button type="submit" name="order" value="desc">価格の降順▼</button>
</form>
(4) 動作確認
http://localhost:8080/search
で検索- 「価格の昇順▲」「価格の降順▼」ボタンを押す
- 価格順に並べ替えられることを確認
ハンズオン:検索フォームを作成して、検索結果を表示する
【目標】
- フォームから入力したキーワードでデータを検索する
【手順】
- 検索フォーム (
search.html
) を作成 - コントローラ (
SearchController.java
) を作成 - DAO (
CarDao.java
) に検索メソッドを追加 - 検索結果 (
search_results.html
) を作成 - ブラウザで
http://localhost:8080/search
にアクセス - 検索と並べ替えが動作することを確認
まとめ
@RequestParam
を使うと、URLのクエリパラメータを取得できるLIKE
を使うと、部分一致検索ができるORDER BY
を使って、昇順・降順の並べ替えができるJdbcTemplate
を使って、データベースと連携できる
次章では、セッションと認証の仕組みを学び、ログイン機能を実装します!
第8章:セッションと認証
8.1 セッションとは?
Webアプリケーションでは、HTTPはステートレス(リクエストごとに情報を保持しない) ため、ログイン状態などを保持するには「セッション」が必要です。
Spring Boot では、HttpSession
を使ってセッション管理 ができます。
8.2 ログイン機能の実装
(1) テーブルの作成
まず、ログインユーザーを管理する login_user
テーブルを作成します。
CREATE TABLE login_user (
id INT AUTO_INCREMENT PRIMARY KEY,
login_id VARCHAR(45) NOT NULL UNIQUE,
password VARCHAR(100) NOT NULL
);
INSERT INTO login_user (login_id, password) VALUES
('user1', 'password1'),
('admin', 'adminpass');
(2) ユーザーモデルの作成
src/main/java/com/example/demo/model/User.java
package com.example.demo.model;
import java.io.Serializable;
public class User implements Serializable {
private int id;
private String loginId;
private String password;
public User() {}
public User(int id, String loginId, String password) {
this.id = id;
this.loginId = loginId;
this.password = password;
}
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getLoginId() { return loginId; }
public void setLoginId(String loginId) { this.loginId = loginId; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
(3) DAOの作成
ユーザー情報を取得するDAOを作成します。
src/main/java/com/example/demo/model/UserDao.java
package com.example.demo.model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
@Repository
public class UserDao {
private final JdbcTemplate jdbcTemplate;
@Autowired
public UserDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public User findByLoginId(String loginId) {
String sql = "SELECT * FROM login_user WHERE login_id = ?";
return jdbcTemplate.queryForObject(sql, new Object[]{loginId}, new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
return new User(rs.getInt("id"), rs.getString("login_id"), rs.getString("password"));
}
});
}
}
(4) ログインフォームの作成
ユーザーがログインするためのフォームを作成します。
src/main/resources/templates/login.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>ログイン</title>
</head>
<body>
<h1>ログイン</h1>
<form th:action="@{/login}" method="post">
<label>ログインID:</label>
<input type="text" name="loginId" required>
<br>
<label>パスワード:</label>
<input type="password" name="password" required>
<br>
<button type="submit">ログイン</button>
</form>
<p th:if="${error}" style="color:red;">ログインIDまたはパスワードが違います。</p>
</body>
</html>
(5) ログイン処理
セッションを使って、ログイン状態を管理します。
src/main/java/com/example/demo/controller/LoginController.java
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.model.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import jakarta.servlet.http.HttpSession;
@Controller
public class LoginController {
private final UserDao userDao;
@Autowired
public LoginController(UserDao userDao) {
this.userDao = userDao;
}
@GetMapping("/login")
public String showLoginForm() {
return "login";
}
@PostMapping("/login")
public String login(@RequestParam String loginId, @RequestParam String password, HttpSession session, Model model) {
try {
User user = userDao.findByLoginId(loginId);
if (user != null && user.getPassword().equals(password)) {
session.setAttribute("loginUser", user);
return "redirect:/mypage";
}
} catch (Exception e) {
// ログイン失敗時
}
model.addAttribute("error", true);
return "login";
}
@GetMapping("/logout")
public String logout(HttpSession session) {
session.invalidate();
return "redirect:/login";
}
}
(6) マイページの作成
ログイン後のページを作成し、セッション情報を表示します。
src/main/resources/templates/mypage.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>マイページ</title>
</head>
<body>
<h1>マイページ</h1>
<p>ようこそ、<span th:text="${loginUser.loginId}">ゲスト</span> さん!</p>
<a href="/logout">ログアウト</a>
</body>
</html>
(7) マイページのコントローラ
src/main/java/com/example/demo/controller/MyPageController.java
package com.example.demo.controller;
import com.example.demo.model.User;
import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class MyPageController {
@GetMapping("/mypage")
public String myPage(HttpSession session, Model model) {
User loginUser = (User) session.getAttribute("loginUser");
if (loginUser == null) {
return "redirect:/login";
}
model.addAttribute("loginUser", loginUser);
return "mypage";
}
}
8.3 ログイン機能の動作確認
【目標】
ログインフォームからユーザーが認証できるようにする。
【手順】
http://localhost:8080/login
にアクセス- ログインIDとパスワードを入力
- 「ログイン」ボタンを押す
- マイページ (
http://localhost:8080/mypage
) にリダイレクトされる - 「ログアウト」ボタンを押すと、ログアウトして
/login
に戻る
まとめ
HttpSession
を使って ログイン状態を管理 する@RequestParam
で フォームの入力を取得 する@PostMapping
を使って ログイン処理を実装 する- ログイン後の画面 (
mypage.html
) を作成し、セッション情報を表示
次章では、簡易的な販売管理システムを作成し、アプリケーションの統合を行います!
第9章:簡易的な販売管理システムの作成
9.1 アプリの仕様設計
この章では、Spring Boot を使って簡易的な販売管理システムを作成 します。
システムの機能
✅ ログイン機能(前章で実装済み)
✅ 車の一覧表示(第5章で実装済み)
✅ 車の購入機能(新規追加)
✅ 購入履歴の表示機能(新規追加)
9.2 データベースの設計
(1) sales テーブルの作成
車の購入履歴を管理する sales
テーブルを作成します。
CREATE TABLE sales (
sale_id INT AUTO_INCREMENT PRIMARY KEY,
car_id INT NOT NULL,
customer_id INT NOT NULL,
saleDateTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (car_id) REFERENCES cars(car_id),
FOREIGN KEY (customer_id) REFERENCES login_user(id)
);
9.3 車の購入機能の実装
(1) DAOの作成
JdbcTemplate
を使って、車の購入データを登録します。
src/main/java/com/example/demo/model/SaleDao.java
package com.example.demo.model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class SaleDao {
private final JdbcTemplate jdbcTemplate;
@Autowired
public SaleDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public int addSale(int carId, int customerId) {
String sql = "INSERT INTO sales (car_id, customer_id) VALUES (?, ?)";
return jdbcTemplate.update(sql, carId, customerId);
}
}
(2) コントローラの作成
車を購入すると、sales
テーブルにデータが追加されるようにします。
src/main/java/com/example/demo/controller/SaleController.java
package com.example.demo.controller;
import com.example.demo.model.SaleDao;
import com.example.demo.model.User;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class SaleController {
private final SaleDao saleDao;
@Autowired
public SaleController(SaleDao saleDao) {
this.saleDao = saleDao;
}
@GetMapping("/purchase")
public String purchase(@RequestParam int carId, HttpSession session) {
User loginUser = (User) session.getAttribute("loginUser");
if (loginUser == null) {
return "redirect:/login";
}
saleDao.addSale(carId, loginUser.getId());
return "redirect:/mypage";
}
}
(3) 購入ボタンの追加
購入ボタンを car_list.html
に追加します。
src/main/resources/templates/car_list.html
<tr th:each="car : ${cars}">
<td th:text="${car.carId}"></td>
<td th:text="${car.name}"></td>
<td th:text="${car.price}"></td>
<td>
<a th:href="@{/purchase(carId=${car.carId})}">購入</a>
</td>
</tr>
(4) 動作確認
http://localhost:8080/cars
にアクセス- 購入ボタンを押す
- データベースの
sales
テーブルにデータが登録されているか確認
9.4 購入履歴の表示
(1) DAOの作成
sales
テーブルから購入履歴を取得します。
src/main/java/com/example/demo/model/SaleDao.java
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.RowMapper;
public List<String> getSalesByUserId(int customerId) {
String sql = "SELECT c.name FROM sales s INNER JOIN cars c ON s.car_id = c.car_id WHERE s.customer_id = ?";
return jdbcTemplate.query(sql, new Object[]{customerId}, new RowMapper<String>() {
@Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getString("name");
}
});
}
(2) コントローラの作成
src/main/java/com/example/demo/controller/MyPageController.java
package com.example.demo.controller;
import com.example.demo.model.SaleDao;
import com.example.demo.model.User;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
@Controller
public class MyPageController {
private final SaleDao saleDao;
@Autowired
public MyPageController(SaleDao saleDao) {
this.saleDao = saleDao;
}
@GetMapping("/mypage")
public String myPage(HttpSession session, Model model) {
User loginUser = (User) session.getAttribute("loginUser");
if (loginUser == null) {
return "redirect:/login";
}
List<String> sales = saleDao.getSalesByUserId(loginUser.getId());
model.addAttribute("loginUser", loginUser);
model.addAttribute("sales", sales);
return "mypage";
}
}
(3) マイページの修正
src/main/resources/templates/mypage.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>マイページ</title>
</head>
<body>
<h1>マイページ</h1>
<p>ようこそ、<span th:text="${loginUser.loginId}">ゲスト</span> さん!</p>
<h2>購入履歴</h2>
<ul>
<li th:each="sale : ${sales}" th:text="${sale}"></li>
</ul>
<a href="/logout">ログアウト</a>
</body>
</html>
(4) 動作確認
http://localhost:8080/cars
で車を購入http://localhost:8080/mypage
にアクセス- 購入履歴が表示されることを確認
9.5 ハンズオン:完成した販売管理アプリを動かしてみる
【目標】
- ログイン → 車の購入 → 購入履歴を確認する の一連の流れを実装する。
【手順】
sales
テーブルを作成- DAO (
SaleDao.java
) を作成 - 購入処理 (
SaleController.java
) を実装 - 購入履歴の表示 (
MyPageController.java
) を実装 - ブラウザで購入し、購入履歴が正しく表示されることを確認
まとめ
INSERT
を使って 購入データを登録INNER JOIN
を使って 購入履歴を取得HttpSession
を使って ログイン状態を管理- Thymeleaf を使って 購入履歴を表示
🚀 おめでとうございます! 簡易的な販売管理システムが完成しました!
次章では、全体の統合とアプリの改善点をまとめます。
第10章:アプリケーションの統合と改善
10.1 アプリケーションの全体構成
これまでの章で実装した機能を統合し、販売管理システムとして完成させます。
各機能を整理し、アプリケーションの構成を振り返ります。
✅ 実装した機能
機能 | 概要 |
---|---|
ログイン機能 | ユーザー認証を行い、セッション管理をする |
車の一覧表示 | MySQL の cars テーブルからデータを取得して表示 |
車の検索機能 | LIKE を使用して検索 |
車の並べ替え | 価格の昇順・降順にソート |
車の購入機能 | 購入したデータを sales テーブルに登録 |
購入履歴の表示 | ユーザーごとの購入履歴を sales テーブルから取得 |
🔧 改善ポイント
- ログインしていないユーザーのアクセス制限
- セキュリティの強化(パスワードのハッシュ化)
- UI の整理(メニューの追加)
- 例外処理の追加(エラーハンドリング)
10.2 ログインしていないユーザーのアクセス制限
現在の状態では、ログインしなくても /cars
や /mypage
にアクセスできます。
これを制限するために、ログインしていない場合は /login
にリダイレクトするように修正します。
(1) アクセス制限を追加
各コントローラで、ログイン状態をチェックし、未ログインの場合はリダイレクトします。
src/main/java/com/example/demo/controller/MyPageController.java
@GetMapping("/mypage")
public String myPage(HttpSession session, Model model) {
User loginUser = (User) session.getAttribute("loginUser");
if (loginUser == null) {
return "redirect:/login";
}
List<String> sales = saleDao.getSalesByUserId(loginUser.getId());
model.addAttribute("loginUser", loginUser);
model.addAttribute("sales", sales);
return "mypage";
}
src/main/java/com/example/demo/controller/CarController.java
@GetMapping("/cars")
public String listCars(HttpSession session, Model model) {
if (session.getAttribute("loginUser") == null) {
return "redirect:/login";
}
List<Car> cars = carDao.getCars();
model.addAttribute("cars", cars);
return "car_list";
}
10.3 セキュリティの強化(パスワードのハッシュ化)
現在はプレーンテキストのパスワードをデータベースに保存していますが、
セキュリティの観点から、ハッシュ化 して保存するように変更します。
(1) パスワードのハッシュ化
Spring Security の BCryptPasswordEncoder
を使ってパスワードを暗号化します。
(a) 依存関係を追加
pom.xml
に以下の依存関係を追加。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
(b) パスワードをハッシュ化
UserDao
にパスワードをハッシュ化して保存する処理を追加します。
src/main/java/com/example/demo/model/UserDao.java
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public int registerUser(String loginId, String password) {
String sql = "INSERT INTO login_user (login_id, password) VALUES (?, ?)";
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String hashedPassword = encoder.encode(password);
return jdbcTemplate.update(sql, loginId, hashedPassword);
}
(c) ログイン時にハッシュ化されたパスワードを比較
LoginController.java
@PostMapping("/login")
public String login(@RequestParam String loginId, @RequestParam String password, HttpSession session, Model model) {
try {
User user = userDao.findByLoginId(loginId);
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
if (user != null && encoder.matches(password, user.getPassword())) {
session.setAttribute("loginUser", user);
return "redirect:/mypage";
}
} catch (Exception e) {
// ログイン失敗
}
model.addAttribute("error", true);
return "login";
}
10.4 メニューの追加
アプリのナビゲーションを改善するため、メニューを追加 します。
(1) メニューを作成
src/main/resources/templates/menu.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>メニュー</title>
</head>
<body>
<h1>メニュー</h1>
<ul>
<li><a href="/mypage">マイページ</a></li>
<li><a href="/cars">車一覧</a></li>
<li><a href="/search">車の検索</a></li>
<li><a href="/logout">ログアウト</a></li>
</ul>
</body>
</html>
(2) 各ページにメニューを組み込み
各ページの先頭に以下のコードを追加します。
<div th:replace="menu :: *"></div>
10.5 例外処理の追加
データベース接続エラーや存在しないデータを取得したときのために、エラーハンドリングを追加します。
(1) グローバルエラーハンドリング
Spring Boot の @ControllerAdvice
を使い、アプリ全体のエラーをキャッチします。
src/main/java/com/example/demo/exception/GlobalExceptionHandler.java
package com.example.demo.exception;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public String handleException(Exception e, Model model) {
model.addAttribute("errorMessage", "エラーが発生しました: " + e.getMessage());
return "error";
}
}
(2) エラーページの作成
src/main/resources/templates/error.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>エラー</title>
</head>
<body>
<h1>エラーが発生しました</h1>
<p th:text="${errorMessage}"></p>
<a href="/">トップページへ戻る</a>
</body>
</html>
10.6 動作確認
【目標】
全体の動作を統合し、本番環境に近い形でアプリケーションを動作させる。
【手順】
- ログインしていない状態で
/cars
にアクセスし、リダイレクトされるか確認 - パスワードのハッシュ化が適用されているか確認
- メニューが正しく表示され、ナビゲーションできるか確認
- エラー発生時に
error.html
が表示されるか確認
まとめ
- ログインしていないユーザーを
/login
にリダイレクト - パスワードを
BCryptPasswordEncoder
でハッシュ化 - メニューを追加して UI を改善
@ControllerAdvice
を使い、エラー処理を統一
🎉 おめでとうございます! 本書のゴールである Spring Boot を使ったWebアプリケーションの完成 です! 🚀
このアプリをベースに、機能を拡張していくことで、さらに実践的なスキルを磨けます!
セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク
投稿者プロフィール

- 代表取締役
-
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。