カテゴリ: Spring 更新日: 2026/01/15

Springでファイルアップロードを安全に!サイズ・拡張子・MIMEタイプのバリデーション方法を解説

ファイルアップロードの検証:サイズ/拡張子/MIMEタイプチェック
ファイルアップロードの検証:サイズ/拡張子/MIMEタイプチェック

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

生徒

「Springのフォームでファイルアップロードさせたいんですが、危ないファイルとかアップされないようにしたいんです。」

先生

「それは大事なポイントですね。ファイルアップロードでは、ファイルサイズ拡張子MIMEタイプをきちんとチェックして、不正なファイルを防ぐことが重要です。」

生徒

「それってSpringの機能で簡単にできますか?」

先生

「はい、Springではバリデーションやフォームバインドを使って、しっかりと検証ができますよ。実際にやり方を見ていきましょう。」

1. Springでファイルアップロードを受け取る基本設定

1. Springでファイルアップロードを受け取る基本設定
1. Springでファイルアップロードを受け取る基本設定

Spring MVCでは、ファイルアップロードの処理にMultipartFileインタフェースを使用します。まずはHTMLフォーム側でファイルを送信できるようにしましょう。


<form method="post" enctype="multipart/form-data" th:action="@{/upload}" th:object="${form}">
    <input type="file" th:field="*{file}" class="form-control" />
    <button type="submit" class="btn btn-primary mt-2">アップロード</button>
</form>

Spring側では、コントローラーに@ModelAttributeでフォームを受け取り、MultipartFileとしてファイルを扱います。


@Controller
public class FileUploadController {

    @PostMapping("/upload")
    public String handleUpload(@ModelAttribute FileForm form, Model model) {
        MultipartFile file = form.getFile();
        // 検証ロジックをここに実装
        return "result";
    }
}

2. ファイルサイズを検証する方法

2. ファイルサイズを検証する方法
2. ファイルサイズを検証する方法

セキュリティの基本として、ファイルサイズの上限を設けることは必須です。Springでは設定ファイルで制限する方法と、コードでチェックする方法があります。

まずはapplication.propertiesで最大サイズを指定します。


spring.servlet.multipart.max-file-size=5MB
spring.servlet.multipart.max-request-size=5MB

さらに、プログラム内で細かくチェックするには次のように記述します。


if (file.getSize() > 5 * 1024 * 1024) {
    bindingResult.rejectValue("file", "file.tooLarge", "ファイルサイズは5MB以下にしてください");
}

このようにすると、バリデーションエラーを発生させて、ユーザーにメッセージを表示できます。

3. 拡張子のバリデーションチェック

3. 拡張子のバリデーションチェック
3. 拡張子のバリデーションチェック

ファイルの拡張子(例:.jpg.pdf)をチェックすることで、不正なファイル形式のアップロードを防ぎます。


String filename = file.getOriginalFilename();
if (filename != null && !filename.matches(".*\\.(jpg|jpeg|png|pdf)$")) {
    bindingResult.rejectValue("file", "file.invalidType", "許可されていないファイル形式です");
}

ただし、拡張子だけでは完全な判定にはなりません。次はMIMEタイプの確認もあわせて行いましょう。

4. MIMEタイプ(コンテンツタイプ)の検証方法

4. MIMEタイプ(コンテンツタイプ)の検証方法
4. MIMEタイプ(コンテンツタイプ)の検証方法

ファイルの中身が本当に画像かPDFかを確認するには、MIMEタイプ(Content-Type)を確認します。


String contentType = file.getContentType();
if (contentType == null || 
    !(contentType.equals("image/jpeg") || contentType.equals("image/png") || contentType.equals("application/pdf"))) {
    bindingResult.rejectValue("file", "file.invalidMime", "許可されていないMIMEタイプです");
}

このようにすれば、拡張子を偽装したファイルをブロックすることが可能です。セキュリティ対策として重要です。

5. カスタムバリデーターを使って検証をまとめる

5. カスタムバリデーターを使って検証をまとめる
5. カスタムバリデーターを使って検証をまとめる

毎回コントローラーにバリデーションを書くのは煩雑です。SpringのValidatorインタフェースを使って、検証を共通化しましょう。


@Component
public class FileValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return FileForm.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        FileForm form = (FileForm) target;
        MultipartFile file = form.getFile();

        if (file == null || file.isEmpty()) {
            errors.rejectValue("file", "file.empty", "ファイルが選択されていません");
            return;
        }

        if (file.getSize() > 5 * 1024 * 1024) {
            errors.rejectValue("file", "file.tooLarge", "ファイルサイズは5MB以下にしてください");
        }

        String filename = file.getOriginalFilename();
        if (filename != null && !filename.matches(".*\\.(jpg|jpeg|png|pdf)$")) {
            errors.rejectValue("file", "file.invalidType", "許可されていないファイル形式です");
        }

        String contentType = file.getContentType();
        if (contentType == null || 
            !(contentType.equals("image/jpeg") || contentType.equals("image/png") || contentType.equals("application/pdf"))) {
            errors.rejectValue("file", "file.invalidMime", "許可されていないMIMEタイプです");
        }
    }
}

このようにすることで、コントローラー側はスッキリしたコードになります。

6. コントローラーでValidatorを使用する

6. コントローラーでValidatorを使用する
6. コントローラーでValidatorを使用する

バリデーターをコントローラーで使うには、次のように@InitBinderで登録します。


@Controller
public class FileUploadController {

    @Autowired
    private FileValidator fileValidator;

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.addValidators(fileValidator);
    }

    @PostMapping("/upload")
    public String upload(@ModelAttribute("form") @Validated FileForm form, BindingResult result) {
        if (result.hasErrors()) {
            return "form";
        }

        // 正常なファイル処理
        return "success";
    }
}

このように@ValidatedBindingResultを併用することで、ファイルアップロードのバリデーション処理を自動化できます。

7. よくあるエラーとデバッグポイント

7. よくあるエラーとデバッグポイント
7. よくあるエラーとデバッグポイント

ファイルバリデーションでよくある失敗例や見落としポイントも押さえておきましょう。

  • ファイルサイズ制限が効かない ⇒ application.propertiesで指定したか確認
  • MIMEタイプが常にapplication/octet-streamになる ⇒ ブラウザやアップロード手段に依存
  • 拡張子チェックが甘い ⇒ .exeなど明示的に除外が必要

検証ロジックは常に攻撃を想定して実装することが、安全なアプリケーションには欠かせません。

Spring FrameworkやThymeleafを使った Webアプリ開発の全体像をやさしく理解したい人には、 この入門書が定番です。

Spring Framework超入門をAmazonで見る

※ Amazon広告リンク

関連記事:
カテゴリの一覧へ
新着記事
New1
Spring
SpringDataJPAのJPAクエリメソッド「StartingWith」の使い方を完全ガイド!初心者向け解説
更新記事
New2
Spring
SpringDataJPAのJPAクエリメソッド「NotLike」の使い方を完全ガイド!初心者向け解説
更新記事
New3
Thymeleaf
Thymeleafのth:style属性を完全ガイド!初心者でもわかる動的スタイルの適用方法
更新記事
New4
Servlet
JavaのPart.getSubmittedFileNameメソッドの使い方を徹底解説!初心者でもわかるファイル名の取得方法
更新記事
人気記事
No.1
Java&Spring記事人気No1
Spring
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.2
Java&Spring記事人気No2
Servlet
JavaのHttpSessionを徹底解説!初心者でもわかるセッション管理の基本
No.3
Java&Spring記事人気No3
Spring
Springの@Componentアノテーションの使い方を徹底解説!初心者でもわかるSpring Boot入門
No.4
Java&Spring記事人気No4
Spring
Spring Data JPA入門!findAll()やfindBy**()の使い方などデータベース操作の基礎を学ぶ
No.5
Java&Spring記事人気No5
Spring
Springの@Serviceアノテーションの使い方を徹底解説!初心者でもわかるSpring フレームワーク入門
No.6
Java&Spring記事人気No6
Spring
SpringのModelクラスの使い方を完全ガイド!初心者でも安心
No.7
Java&Spring記事人気No7
Java
Javaの@SuppressWarningsアノテーションの使い方を完全ガイド!初心者でもわかる警告の抑制方法
No.8
Java&Spring記事人気No8
JSP
JSPの基本タグ一覧と使い方まとめ!実務で使えるタグを紹介

💻 作業効率アップに

長時間のコーディングでも疲れにくい♪ 静音ワイヤレスマウス

Logicool Signature M750 を見る

※ Amazon広告リンク