カテゴリ: Spring 更新日: 2025/12/23

Spring BootでRangeリクエストに対応する方法!初心者でもわかる部分コンテンツ配信の実装

Spring BootのRangeリクエスト対応:部分コンテンツ配信の実装
Spring BootのRangeリクエスト対応:部分コンテンツ配信の実装

先生と生徒の会話形式で理解しよう

生徒

「先生、動画をストリーミング再生したいんですが、Spring Bootで部分的にファイルを配信するにはどうすればいいですか?」

先生

「それはRangeリクエストに対応すれば実現できますよ。動画や音声の途中再生にも必要な技術です。」

生徒

「Rangeリクエストってよく聞きますけど、どういう仕組みなんですか?」

先生

「ブラウザやプレイヤーがファイルの一部だけをリクエストして、サーバーがその範囲だけを返す機能です。さっそく実装方法を見てみましょう!」

1. Rangeリクエストとは何か?仕組みと用途

1. Rangeリクエストとは何か?仕組みと用途
1. Rangeリクエストとは何か?仕組みと用途

Rangeリクエストとは、HTTPヘッダーRangeを使って、特定のバイト範囲だけを取得する仕組みです。たとえば音声や動画のストリーミング、PDFの途中表示、ファイルのダウンロード再開などに使われます。

クライアントがRange: bytes=0-999というリクエストを送ると、サーバーはその範囲のデータだけを返します。そしてレスポンスには206 Partial Contentが含まれます。

2. Spring BootでRangeリクエストを処理する方法

2. Spring BootでRangeリクエストを処理する方法
2. Spring BootでRangeリクエストを処理する方法

Spring BootにはRangeに自動対応する仕組みはありません。自分でRangeヘッダーを読み取り、レスポンスの一部を返す実装を行う必要があります。

以下は動画ファイルを部分配信するサンプルコードです。


@GetMapping("/video")
public void streamVideo(HttpServletRequest request, HttpServletResponse response) throws IOException {
    File video = new File("sample.mp4");
    int length = (int) video.length();
    String range = request.getHeader("Range");

    int start = 0;
    int end = length - 1;

    if (range != null && range.startsWith("bytes=")) {
        String[] parts = range.replace("bytes=", "").split("-");
        start = Integer.parseInt(parts[0]);
        if (parts.length > 1) {
            end = Integer.parseInt(parts[1]);
        }
    }

    int contentLength = end - start + 1;

    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
    response.setContentType("video/mp4");
    response.setHeader("Accept-Ranges", "bytes");
    response.setHeader("Content-Range", "bytes " + start + "-" + end + "/" + length);
    response.setHeader("Content-Length", String.valueOf(contentLength));

    try (InputStream input = new FileInputStream(video);
         OutputStream output = response.getOutputStream()) {
        input.skip(start);
        byte[] buffer = new byte[8192];
        int bytesRead;
        int bytesToRead = contentLength;

        while ((bytesRead = input.read(buffer, 0, Math.min(buffer.length, bytesToRead))) != -1) {
            output.write(buffer, 0, bytesRead);
            bytesToRead -= bytesRead;
            if (bytesToRead <= 0) break;
        }
        output.flush();
    }
}

3. レスポンスヘッダーのポイントとHTTPステータスコード

3. レスポンスヘッダーのポイントとHTTPステータスコード
3. レスポンスヘッダーのポイントとHTTPステータスコード

部分コンテンツ配信のレスポンスでは、以下のHTTPヘッダーが必須です。

  • Content-Range:配信したバイト範囲を示す
  • Accept-Rangesbytesを指定し、Range対応を明示
  • Content-Length:配信する範囲の長さ

そして、HTTPステータスコードには必ず206 Partial Contentを返す必要があります。

4. 音声ファイル・PDF・ZIPにも対応可能

4. 音声ファイル・PDF・ZIPにも対応可能
4. 音声ファイル・PDF・ZIPにも対応可能

Rangeリクエストは動画以外にも、以下の用途で非常に有効です。

  • 音声ファイルの途中再生(audio/mpeg
  • PDFの特定ページ表示(application/pdf
  • 大容量のZIPファイルの断続的ダウンロード

Content-Typeは用途に応じて変更しましょう。

5. Rangeの形式と異常系への対応

5. Rangeの形式と異常系への対応
5. Rangeの形式と異常系への対応

Rangeヘッダーは基本的にbytes=start-end形式で送られますが、bytes=500-(末尾まで)やbytes=-500(最後の500バイト)などの形式にも対応する必要があります。

また、不正なRangeや範囲外の値が指定された場合は、416 Range Not Satisfiableを返すことも検討しましょう。

6. Range対応とセキュリティ対策の注意点

6. Range対応とセキュリティ対策の注意点
6. Range対応とセキュリティ対策の注意点

Rangeリクエストは便利ですが、DoS攻撃(大量の細かいRange指定)に悪用される可能性もあります。そのため以下のような制限を設けると安全です。

  • 1リクエストあたり1つのRangeのみ許可する
  • 過剰に小さい範囲のリクエストを拒否する
  • ログにリクエスト範囲を記録し監視する

7. クライアント側の検証方法(Range動作確認)

7. クライアント側の検証方法(Range動作確認)
7. クライアント側の検証方法(Range動作確認)

curlコマンドを使って、手動でRangeリクエストを確認することもできます。


curl -H "Range: bytes=0-1023" http://localhost:8080/video --output partial.mp4

また、Chromeの開発者ツールの「Network」タブで、Rangeヘッダーや206ステータスが使われていることも確認できます。

まとめ

まとめ
まとめ

Rangeリクエスト対応でできることの整理

この記事では、Spring BootでRangeリクエストに対応する方法について、基礎から実装例までを順番に解説してきました。 Rangeリクエストは、HTTP通信の中でも少し理解が難しい分野ですが、仕組みを正しく理解すれば、 動画ストリーミングや音声再生、PDFの部分表示、大容量ファイルのダウンロード再開といった、 現代のWebアプリケーションでは欠かせない機能を実現できます。

特にSpring Bootでは、Rangeリクエストを自動で処理してくれる仕組みがないため、 HTTPヘッダーを自分で読み取り、レスポンスヘッダーやステータスコードを正しく設定する必要があります。 その分、HTTPの基礎知識やレスポンスの意味を深く理解できる良い題材でもあります。

実装時に押さえておきたい重要ポイント

Range対応の実装で特に重要なのは、「どの範囲のデータを返すのか」を正確に計算することと、 その結果をHTTPレスポンスとして正しく伝えることです。 Content-RangeAccept-RangesContent-Length といったヘッダーは、 クライアント側が正しく再生や表示を行うための重要な情報になります。

また、ステータスコードに 206 Partial Content を返すことも忘れてはいけません。 これがないと、ブラウザや動画プレイヤーが「部分配信」として認識せず、 正しく動作しない原因になります。

Rangeリクエスト対応のシンプルな流れ


① クライアントから Range ヘッダーを受け取る
② 開始位置と終了位置を計算する
③ 206 Partial Content を設定する
④ Content-Range や Content-Length を設定する
⑤ ファイルの指定範囲だけをレスポンスとして返す

上記の流れを意識して実装すれば、動画配信や音声配信といった機能も、 一つひとつ落ち着いて作れるようになります。 最初は難しく感じるかもしれませんが、処理の流れ自体はとてもシンプルです。

セキュリティと実務視点での注意点

Rangeリクエストは非常に便利な一方で、悪意のある使われ方をする可能性もあります。 細かいRange指定を大量に送られると、サーバーに負荷がかかる場合もあるため、 実務ではリクエストの制限やログ監視といった対策が重要になります。

初心者のうちは、まず正しく動く実装を目指し、 その後にセキュリティやパフォーマンスを意識して改善していく流れがおすすめです。 Range対応は「作って終わり」ではなく、「運用まで考える」ことで本当の理解につながります。

先生と生徒の振り返り会話

生徒

「最初はRangeリクエストって難しそうだと思っていましたけど、 仕組みを一つずつ見ていくと、意外と流れはシンプルなんですね。」

先生

「そうですね。HTTPヘッダーとレスポンスの役割が分かれば、 Spring Bootでも落ち着いて実装できるようになります。」

生徒

「動画の途中再生やPDFの部分表示が、こういう仕組みで動いていると知って、 Webの裏側が少し分かった気がします。」

先生

「それはとても良い理解です。Rangeリクエストは、 Webアプリケーションの実務でもよく使われる知識なので、 今回の内容は今後きっと役に立ちますよ。」

生徒

「次はエラー対応やセキュリティ面も意識しながら、 もう一度コードを書いてみようと思います!」

先生

「その姿勢が大切です。ぜひ自分の手で試しながら、 Spring BootとHTTPの理解を深めていきましょう。」

Springの学習を効率化したい方へ

この記事の内容をもっと深く知るには、以下の入門書が最適です。

Spring Framework超入門をAmazonで見る
カテゴリの一覧へ
新着記事
New1
Spring
SpringDataJPAのJPAクエリメソッド「EndingWith」の使い方を完全ガイド!初心者向け解説
更新記事
New2
Spring
SpringDataJPAのJPAクエリメソッド「StartingWith」の使い方を完全ガイド!初心者向け解説
更新記事
New3
Spring
SpringDataJPAのJPAクエリメソッド「NotLike」の使い方を完全ガイド!初心者向け解説
更新記事
New4
Spring
SpringDataJPAのJPAクエリメソッド「Like」の使い方を完全ガイド!初心者向け解説
更新記事
人気記事
No.1
Java&Spring記事人気No1
Spring
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.2
Java&Spring記事人気No2
Java
JavaのBooleanクラスの使い方を完全ガイド!初心者でもわかる真偽値の操作
No.3
Java&Spring記事人気No3
Java
JavaのIOExceptionクラス徹底解説!初心者向けファイル入出力エラー対策ガイド
No.4
Java&Spring記事人気No4
JSP
JSPの基本タグ一覧と使い方まとめ!実務で使えるタグを紹介
No.5
Java&Spring記事人気No5
Spring
SpringのBindingResultを完全ガイド!初心者でもわかる入力チェックとエラー処理
No.6
Java&Spring記事人気No6
JSP
JSPでif文・for文を使う方法!初心者でもわかるJavaとの違いと使い方
No.7
Java&Spring記事人気No7
Spring
SpringのModelクラスとaddAttributeメソッドの使い方を完全ガイド!初心者でも安心
No.8
Java&Spring記事人気No8
Spring
SpringDataJPAのJPAクエリメソッド「EndingWith」の使い方を完全ガイド!初心者向け解説