1. test 1
  2. test 2
  3. test 3
  4. test 4
  5. test 5
  6. test 6
コース一覧
Spring Boot入門
サーブレットからフレームワークへ

Spring Boot入門

Java で Web API サーバーを作るための Spring Boot の入門コースです。DI コンテナ、REST コントローラ、リクエスト検証、レイヤ分割、Spring Data JPA、例外ハンドリング、テストまでを扱います。毎レッスン、Spring が裏側でやっている判断そのものを pure Java の関数として自分で書き、フレームワークが何を肩代わりしてくれているのかを手触りで理解できる構成にしました。約 12 時間 (1 日 30 分 × 24 日) で 48 レッスンを修了できます。

1
Spring Bootとは何か
01. Spring Bootで何が作れるのか10分
02. サーブレットからフレームワークへ15分
03. ルーティング表という発想15分
04. プロジェクトの構成10分
05. 起動のしくみと自動設定15分
06. パスのマッチング15分
2
DIコンテナ
01. newで書くと何が困るのか15分
02. コンストラクタインジェクション15分
03. インターフェースへの依存15分
04. @Componentと@Bean15分
05. 自作のDIコンテナ20分
06. Beanのスコープとライフサイクル15分
3
RESTコントローラ
01. RESTという設計方針15分
02. @RestControllerの役割15分
03. @GetMappingとパス変数15分
04. クエリパラメータの受け取り15分
05. @PostMappingとリクエストボディ15分
06. ステータスコードの選び方15分
07. ResponseEntityで組み立てる15分
4
リクエストとレスポンスの変換
01. JSONとオブジェクトの往復15分
02. DTOとエンティティを分ける15分
03. recordでDTOを書く15分
04. 入力検証の基本15分
05. 検証エラーをまとめて返す15分
06. アノテーションによる検証15分
5
レイヤ構成とビジネスロジック
01. 3層アーキテクチャ10分
02. @Serviceに置くもの15分
03. 状態遷移をルールにする15分
04. 料金計算のような業務ロジック15分
05. @Transactionalとは何か15分
06. トランザクションの巻き戻し15分
6
データアクセス
01. @Entityとテーブルの対応15分
02. リポジトリという抽象15分
03. メソッド名からクエリを作る20分
04. 検索条件の組み立て15分
05. ページングと並び替え15分
06. N+1問題15分
7
例外処理と横断的関心事
01. 例外をHTTPに変換する15分
02. @ExceptionHandlerと@ControllerAdvice15分
03. エラーレスポンスの形を決める15分
04. フィルタとインターセプタ15分
05. ログとリクエストの追跡15分
06. 設定値の外部化15分
8
テストと仕上げ
01. テストの種類と使い分け15分
02. Serviceの単体テスト15分
03. モックで依存を差し替える15分
04. MockMvcでエンドポイントを試す15分
05. 本番へ出すための次の一歩10分

サーブレットからフレームワークへ

このレッスンでは、Web サーバーに届く HTTP リクエストが本当はただの文字列であることを確かめ、Spring Boot がその文字列をどこまで面倒みてくれているのかを掴みます。

HTTP リクエストは、ただのテキストです

ブラウザのアドレス欄に URL を打ち込むと、裏側ではサーバーに向けて次のようなテキストが送られています。

プレーンテキスト

GET /users/12 HTTP/1.1 Host: example.com Accept: application/json User-Agent: Mozilla/5.0

1 行目を リクエストライン と呼びます。半角スペース区切りで 3 つの要素が並んでいて、順に HTTP メソッド、パス、HTTP のバージョンです。2 行目以降が ヘッダ で、名前 と値を区切ってずらりと並びます。ヘッダの最後には空行が 1 行入り、その後ろに ボディ が続きます。POST であればここに JSON が入ります。

つまりサーバーの側から見ると、届くのはバイト列であり、それを人間が決めた規則にしたがって切り刻んでいくのが仕事の始まりです。

サーブレットの時代は、この解析だけは肩代わりされていました

Java の世界には古くから サーブレット という仕様があります。Tomcat のようなサーブレットコンテナが TCP 接続の待ち受けと HTTP の解析を引き受けてくれて、開発者は解析済みのオブジェクトを受け取るところから書けます。

Java

public class UserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException { String path = req.getPathInfo(); // "/12" String id = path.substring(1); // "12" res.setStatus(200); res.setContentType("application/json"); res.getWriter().write("{\"id\":" + id + "}"); } }

たしかに生のバイト列を切り刻む苦労は消えました。それでもまだ大量の手作業が残っています。パスから ID を取り出すのは自分で substring しています。ID が数字でなかったらどうするかも自分で書きます。返す JSON も文字列の連結で組み立てています。項目が 10 個あるオブジェクトになったら、この連結は一瞬で読めなくなります。しかもこのサーブレットをどの URL に結びつけるかは、web.xml という別のファイルに書く必要がありました。

Spring Boot はここまで肩代わりします

同じ処理を Spring Boot で書くと次のようになります。

Java

@RestController public class UserController { @GetMapping("/users/{id}") public User find(@PathVariable Long id) { return userService.findById(id); } }

行数が減ったこと以上に、消えた判断 に注目してください。どの URL のときにこのメソッドを呼ぶかは @GetMapping の 1 行になりました。パスから ID を切り出す処理は @PathVariable が引き受け、しかも String から Long への変換まで済ませてくれます。戻り値の User オブジェクトは Jackson というライブラリが自動で JSON に変換し、Content-Type ヘッダも application/json が自動で付きます。ステータスコードも、正常に返れば 200 が入ります。

肩代わりされているものを整理すると次の通りです。

工程生のサーブレットSpring Boot
TCP と HTTP の解析サーブレットコンテナ組み込み Tomcat
URL とコードの結び付けweb.xml に手書き@GetMapping
パス変数の取り出しと型変換自分で substring@PathVariable
ボディの JSON をオブジェクトへ自分で解析@RequestBody
戻り値を JSON へ自分で文字列連結Jackson が自動変換
ステータスとヘッダ自分で設定既定値が入る

便利ではありますが、この表の左側が「なくなった」わけではありません。誰かがやっています。今回の演習では、その左側の一番入口にあたる処理を自分で書いてみます。

演習でやること

リクエストラインの文字列からメソッドとパスを取り出します。Spring Boot の中では、組み込み Tomcat が毎リクエストこれと同じ切り出しを行い、その結果を使って Spring がどのコントローラのメソッドを呼ぶかを決めています。ここで一度自分で書いておくと、次のレッスンのルーティング表の話がそのまま繋がります。

文字列の分解には String の split を使うのが素直です。"GET /users/12 HTTP/1.1".split(" ") は 3 要素の配列になり、[0] がメソッド、[1] がパスです。ただし現実の入力は必ずしもきれいではないので、要素が 3 つ揃っていない場合の扱いも決めておく必要があります。フレームワークを使わないと、こうした細部が全部自分の責任になる、というのがこのレッスンで一番持ち帰ってほしい感覚です。

要件

  1. リクエストラインを半角スペースで分解し、1つめをメソッド、2つめをパスとして "GET|/users/12" の形で返すこと
  2. 分解した結果が3要素でない場合は "bad-request" を返すこと
  3. 引数が null または空白のみの場合も "bad-request" を返すこと

入出力例

parseRequestLine("GET /users/12 HTTP/1.1") → "GET|/users/12" parseRequestLine("POST /users HTTP/1.1") → "POST|/users" parseRequestLine("DELETE /users/9 HTTP/1.1") → "DELETE|/users/9" parseRequestLine("GET /users") → "bad-request" parseRequestLine(" ") → "bad-request" parseRequestLine("PUT /a/b/c HTTP/1.1") → "PUT|/a/b/c"

ヒント

split(" +") と書くと、スペースが2個以上連続していても1つの区切りとして扱えます

先に trim() で前後の空白を落としておくと、先頭の空白で空要素が生まれる事故を防げます

戻り値は parts[0] + "|" + parts[1] の形です。HTTP のバージョンは使いません

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/08/09

関連レッスン

  • ルーティング表という発想

    メソッドとパスからハンドラを引く表を自分で実装します。

  • プロジェクトの構成

    Spring Initializr が作るディレクトリと build ファイルを読めるようになります。

  • 起動のしくみと自動設定

    @SpringBootApplication が何を束ねているのかを確認します。

  • パスのマッチング

    パス変数を含む URL パターンの照合を実装します。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • サーバークライアント(ブラウザなど)がリクエストを送り、サーバーがレスポンスを返す。
  • HTTPWeb の通信プロトコル、HTTPS は TLS で暗号化したもの
  • リクエストWeb 通信の基本単位、ブラウザの問い合わせとサーバーの返答
  • ブラウザユーザーから見たWebのクライアント
  • URLページの住所全体
  • メソッドクラスに属する関数
  • applicationJSON 本文を送るときの Content-Type
  • サーブレットコンテナServlet を動かすランタイム環境
main.java
学習モード
エディタを読み込んでいます

メモ

サーブレットからフレームワークへ

⌘S で保存