0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Spring入門】第15章 まとめと次のステップ

0
Last updated at Posted at 2026-10-06

社員管理アプリが完成しました。この章では、作ったアプリと学んだことを振り返り、これから現場で出会う技術を紹介します。

この章で学ぶこと

  • 完成したアプリの機能と、それを支える技術の整理
  • アプリ全体の構成と、1つのリクエストが処理される流れ
  • これまでに作った「事故を防ぐ仕組み」の整理
  • この教材で学んだ Spring の用語
  • 次に学ぶとよい技術(Service 層、検索、テスト、ログイン機能、REST API)

15.1 完成したアプリの振り返り

第1章で「完成するとできるようになること」として挙げた機能は、すべて動くようになりました。どの機能を、どの章で、どんな技術を使って作ったかを整理しましょう。

image.png
図15-1 完成した社員一覧画面

機能 章 主な技術
社員一覧 第8章 findAllByOrderByEmpIdAsc、Model、Thymeleaf の th:each・th:text、@ManyToOne による部署名の表示
社員削除 第9章 POST で送るフォーム、@PostMapping、@PathVariable、deleteById、リダイレクトと PRG パターン
社員新規登録 第10章・第11章 フォームクラス、th:object・th:field、@SessionAttributes、確認画面と「戻る」、save(INSERT)、setComplete()
社員変更 第12章 findByEmpId → フォームへの詰め替え、save(UPDATE)
入力チェック 第13章・第14章 Bean Validation(@NotBlank・@NotNull など)、@Validated・BindingResult、messages.properties のエラーメッセージ

その土台として、第2章〜第7章では開発環境、データベース、Spring Boot のプロジェクト、DI、JPA を準備しました。一つひとつは小さな部品ですが、組み合わせることで「データベースとつながる Web アプリケーション」ができあがっています。

15.2 アプリ全体の構成

完成したアプリの部品と、そのつながりを1枚の図にまとめます。

ch15-1.png
図15-2 社員管理アプリの全体構成

部品 役割
Controller URL ごとの処理を書く。一覧・削除、新規登録、変更の3つに分けた
Repository データベースの検索・登録・変更・削除を担当する。インターフェースを書くだけで、中身は Spring が用意する
Entity テーブルの1行分のデータを表すクラス
フォーム 画面の入力内容を受け取るクラス。入力チェックの決まりもここに書く
セッション 入力画面・確認画面・完了画面の間で、入力内容を覚えておく場所
テンプレート Thymeleaf で書いた画面の HTML

完成版のファイル一覧

完成したプロジェクトのファイル構成は次のとおりです。すべてのファイルの内容は 付録A 完成版ソースコード に掲載しています。

employee-app
src/main/java
└─ com.example.employeeapp
    ├─ EmployeeAppApplication.java
    ├─ component
    │   └─ GreetingMessage.java           (第5章の練習用)
    ├─ controller
    │   ├─ HelloController.java           (第4・5章の練習用)
    │   ├─ EmployeeListController.java
    │   ├─ EmployeeRegisterController.java
    │   └─ EmployeeUpdateController.java
    ├─ entity
    │   ├─ Department.java
    │   └─ Employee.java
    ├─ form
    │   ├─ RegisterForm.java
    │   └─ UpdateForm.java
    └─ repository
        ├─ DepartmentRepository.java
        └─ EmployeeRepository.java
src/main/resources
├─ application.properties
├─ messages.properties
├─ static
│   └─ css
│       └─ app.css
└─ templates
    ├─ hello.html                        (第4章の練習用)
    └─ employee
        ├─ list.html
        ├─ register
        │   ├─ input.html
        │   ├─ confirm.html
        │   └─ complete.html
        └─ update
            ├─ input.html
            ├─ confirm.html
            └─ complete.html
src/test/java
└─ com.example.employeeapp
    └─ RepositoryCheckTest.java          (第7章の確認用)

15.3 1つのリクエストの流れのおさらい

学んだことが実際にどうつながっているかを、1つの操作で追いかけてみましょう。例として、変更画面で内容を入力して「確認」ボタンを押したとき の流れです。

  1. ブラウザがリクエストを送る
    Chrome は POST /employees/1/edit/confirm というリクエストを、入力内容と一緒に送ります(第1章)。Cookie の JSESSIONID も一緒に送られるので、サーバーはどのブラウザからのリクエストかがわかります(第10章)。
  2. URL に合うメソッドが選ばれる
    Spring が @PostMapping("/employees/{empId}/edit/confirm") の付いた EmployeeUpdateController の confirm メソッドを探し出します(第4章・第12章)。
  3. セッションからフォームを取り出す
    @SessionAttributes("updateForm") によって、セッションに保存しておいた変更用のフォームが取り出されます(第10章・第12章)。
  4. 入力内容をフォームに詰める
    送られてきた氏名や年齢がフォームに詰められます。
  5. 入力チェックを行う
    @Validated によってフォームのアノテーションの決まりがチェックされ、結果が BindingResult に入ります(第13章・第14章)。
  6. Controller の処理を実行する
    入力チェックでエラーがあれば変更画面、なければ部署を検索して確認画面を選びます。部署の検索は DI で受け取った DepartmentRepository が行い、JPA が SQL を実行します(第5章〜第7章)。
  7. テンプレートで HTML を作る
    Controller が返した "employee/update/confirm" に対応するテンプレートが選ばれ、Thymeleaf が Model とフォームのデータを埋め込んで HTML を作ります(第8章)。
  8. レスポンスが返る
    できあがった HTML がブラウザに返され、確認画面が表示されます。最後に、フォームは再びセッションに保存されます。

【便利な使い方】わからない部分があったら

流れの中でよくわからない部分があれば、カッコ内の章に戻って読み直してみましょう。一度全体を作り終えたあとに読み直すと、最初に読んだときより理解が深まるはずです。

15.4 事故を防ぐ仕組みの整理

第9章から第14章までで、社員管理アプリにはいくつかの「事故を防ぐ仕組み」が入りました。どの問題を、どの仕組みで防いでいるかを整理しておきましょう。

起こりうる問題 防いでいる仕組み 章
リンクを開いただけで、社員が削除される データを変える操作は POST で送る(<form method="post"> と @PostMapping) 第9章
完了画面の再読み込みで、二重に登録・変更・削除される PRG パターン(処理のあと redirect: でリダイレクトする) 第9・11・12章
必須の項目が空のまま、形式の正しくない値のまま登録・変更される 入力チェック(@Validated と BindingResult、messages.properties) 第13・14章
入力チェックは通ったのに、データベースへの登録でエラーになる 入力チェックの文字数の上限を、テーブルの列の長さに合わせる 第13章

15.5 学んだ用語のまとめ

この教材に登場した主な用語です。より詳しい一覧は 付録C 用語集 にまとめています。

用語 意味 章
DI 必要な部品(オブジェクト)を自分で new せず、Spring から受け取る仕組み 第5章
Bean Spring が作って管理しているオブジェクト 第5章
@Controller リクエストを受け取るクラスであることを表す 第4章
@GetMapping / @PostMapping どの URL・どのメソッド(GET / POST)のリクエストを受け取るかを決める 第4章・第9章
Model Controller から画面へデータを渡す入れ物 第4章
Thymeleaf HTML にデータを埋め込むためのテンプレートエンジン 第4章・第8章
JPA Java のオブジェクトとテーブルを対応づける仕組み 第6章
Entity テーブルの1行分を表すクラス(@Entity) 第6章
Repository データベースを操作するためのインターフェース 第7章
@PathVariable URL の一部(社員ID など)を引数で受け取る 第9章
PRG パターン POST のあとはリダイレクトして GET で画面を表示し、二重送信を防ぐ書き方 第9章・第11章
セッション リクエストをまたいでデータを覚えておく、サーバー側の保管場所 第10章
@SessionAttributes 指定した名前のデータを自動でセッションに保存・取り出しする 第10章
Bean Validation アノテーションで入力チェックの決まりを書く仕組み 第13章
BindingResult 入力チェックの結果(エラーの有無と内容)が入る入れ物 第13章

15.6 次のステップ

この教材で作ったアプリは、Web アプリケーションの基本がひととおり詰まったものです。実際の業務システムでは、さらに次のような技術が使われています。ここでは名前と考え方だけを紹介します。

Service 層(3層構成)

この教材では、Controller が Repository を直接使う2層構成で作りました。現場の多くのシステムでは、Controller と Repository の間に、業務の処理をまとめた Service を挟む3層構成にします。

層 役割
Controller リクエストを受け取り、処理の流れを決める司令塔
Service 業務の処理(登録の手順、計算、複数テーブルの更新など)を行う
Repository データベースを操作する

たとえば新規登録の処理を Service に移すと、次のようになります。

EmployeeService.java(例)
@Service
public class EmployeeService {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Autowired
    private DepartmentRepository departmentRepository;

    // 社員を登録する
    @Transactional
    public void register(RegisterForm form) {
        Employee employee = new Employee();
        employee.setName(form.getName());
        // ……(ほかの項目も同じように詰め替える)
        employee.setDepartment(departmentRepository.findByDeptId(form.getDeptId()));
        employeeRepository.save(employee);
    }
}
EmployeeRegisterController.java(complete メソッドの例)
    /** 社員登録の完了画面を表示
     * @param registerForm 入力された社員情報
     * @param sessionStatus セッション破棄時に利用
     * @return 社員登録の完了画面 */
    @PostMapping("/employees/register/complete")
    public String complete(@ModelAttribute RegisterForm registerForm,
            SessionStatus sessionStatus) {
        employeeService.register(registerForm);   // 登録は Service に任せる
        sessionStatus.setComplete();
        return "redirect:/employees/register/done";
    }

Controller は「受け付けて、Service に頼んで、画面を選ぶ」だけになり、見通しがよくなります。同じ登録処理を別の画面から使いたくなったときも、Service を呼ぶだけで済みます。

また、Service のメソッドに付けた @Transactional は、「このメソッドの中のデータベース操作を、まとめて1つのトランザクションにする」という意味です。たとえば「社員を登録し、同時に部署の人数を更新する」のように複数のテーブルを更新するとき、途中で失敗したらすべてを取り消し(ロールバック)、全部成功したときだけ COMMIT できます。

検索とページング

社員が何百人にもなると、一覧をすべて表示するのは現実的ではありません。条件で絞り込む 検索 と、何件かずつに分けて表示する ページング が必要になります。

  • 検索:第7章のクエリメソッドのルールで、たとえば findByNameContaining(String name)(氏名に指定の文字を含む社員を探す)のようなメソッドを宣言するだけで作れます。
  • ページング:Spring Data JPA には、Pageable という「何ページ目を何件ずつ」を表す仕組みが用意されています。

テスト

第7章では JUnit で Repository の動作を確かめました。現場では、プログラムを変更するたびに自動でテストを実行し、壊れていないことを確かめます。

  • JUnit:Java のテストを書くための標準的な仕組み
  • MockMvc:ブラウザを使わずに、Controller にリクエストを送って結果を確かめる Spring の仕組み。「確認ボタンを押したら確認画面が返るか」「入力エラーのときは入力画面に戻るか」などを自動で確認できます

ログイン機能

業務システムでは、ログインした人だけが使える、社員の削除は管理者だけができる、といった制御が必要です。Spring には、ログイン(認証)と権限の管理(認可)を行う Spring Security という仕組みがあります。セキュリティは奥が深い分野なので、公式ドキュメントや専用の資料でしっかり学びましょう。

REST API

この教材の Controller は HTML を返しました。スマートフォンのアプリや、JavaScript で作った画面からデータを使いたい場合は、HTML ではなく JSON という形式でデータを返す REST API を作ります。Spring では、@Controller の代わりに @RestController を付けたクラスで作ることができます。

15.7 現場での心構え

心構え 内容
公式ドキュメントを読む Spring には、詳しい公式ドキュメント(英語)があります。インターネットの記事は古いバージョンの情報であることも多いので、最終的には公式ドキュメントで確かめる習慣をつけましょう
エラーメッセージを最後まで読む エラーの原因は、たいていメッセージの中に書いてあります。長いメッセージでも慌てず、「Caused by」の行や ORA- で始まる番号を探しましょう
よくあるエラーを調べる 付録B よくあるエラーと対処法 に、この教材で出会いやすいエラーをまとめています
チームの決まりに従う 現場には、クラスの名前の付け方やパッケージの分け方などのコーディング規約があります。この教材の書き方と違っていても、チームの決まりを優先しましょう
わからないことは早めに相談する 一人で長時間悩むより、状況(何をしたら、どんなエラーが出たか)を整理して周りの人に相談するほうが、早く解決できます

15.8 おわりに

ここまで、おつかれさまでした。開発環境の準備から始めて、データベースとつながり、一覧・削除・登録・変更・入力チェックを備えた Web アプリケーションを完成させました。

最初は「アノテーションを1つ付けるだけで、なぜ動くのか」と不思議に感じたかもしれません。その裏側では、Spring が決まりきった処理を引き受けてくれていました。仕組みを知ったうえでフレームワークを使えば、新しい機能を作るときにも、エラーに出会ったときにも、落ち着いて対処できるはずです。

このアプリを土台に、検索機能を付けたり、Service 層に書き直したりと、自分で手を加えてみてください。作ってみることが、いちばんの上達の近道です。

15.9 総合確認問題

問1 社員の削除を GET ではなく POST で行うのはなぜですか。

解答を見る

削除はデータを変える操作だからです。GET はリンクをたどったりページを再読み込みしたりするだけで送られてしまうため、意図せず削除が実行されるおそれがあります。データを変える操作は POST で行います(第1章・第9章)。

問2 Controller で new EmployeeRepository() と書かずに Repository を使えるのはなぜですか。

解答を見る

DI の仕組みにより、Spring が Repository の Bean を作り、Controller の @Autowired を付けたフィールドに代入してくれるからです(第5章・第7章)。

問3 新規登録の完了後、完了画面を直接返さずに redirect:/employees/register/done とするのはなぜですか。

解答を見る

完了画面でページを再読み込みしても、POST(登録)が再送されず GET で完了画面を表示し直すだけになり、二重登録を防げるからです(PRG パターン。第9章・第11章)。

問4 同じ save メソッドで、新規登録では INSERT、変更では UPDATE が実行されるのはなぜですか。

解答を見る

主キー(社員ID)の値で判断しているからです。新規登録では社員ID が null のため INSERT になり、シーケンスから取り出した番号が社員ID になります。変更では社員ID が入った Entity を渡すため UPDATE になります(第7章・第11章・第12章)。

問5 入力チェックのエラーメッセージを、Java のコードではなく messages.properties に書くと、どんな良いことがありますか。

解答を見る

メッセージの文言を変えたいときに、Java のコードを直さずに properties ファイルだけを直せばよくなります。また、新規登録と変更のようにフォームを継承している画面で、同じメッセージをそのまま使い回せます(第13章・第14章)。


前へ

第14章 入力チェック② 変更

次へ

付録A 完成版ソースコード

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?