MENU

【SpringBoot】アップロードしたいファイルが画像ファイルなのか判定する方法

こんにちは、くまごろーです。
今日はファイル形式の判別方法についてまとめます。
この前作成したポートフォリオには、アイコン画像設定機能があるんですが、ユーザーがアイコン画像をアップロードする時、誤って画像形式以外のファイルを選択してしまうとエラーが発生していました。イコン画像として加工する前にファイル形式を判別する機能を追加したかったんですが、具体的な方法がわからず中々苦戦しました(-_-;)
 
色々調べて、今回はImageIOを使用することにしました。
 

 
1 ファイルアップロード前に必要なチェックについて
 
ユーザーが任意に指定するファイルをアップロードするには、一番の肝である「ファイル形式のチェック」のほかにもチェックしなきゃいけないことがあります。
羅列すると、

  • ファイルが空でないか
  • ファイル形式が指定されたものか
  • ファイルサイズが大きすぎないか

といった感じになります。 
上記条件のチェック方法としては色々あるとは思いますが、今回は私がやった方法で書いていきます。

 
 
2 ファイルが空でないか
 
今回は「ファイルが空でなく、画像形式のファイルである時」のみ所定の処理を行うよう設定し、「ファイルが空」の場合は何も処理を行わないようにしました。
 
<Controllerクラス>

@PostMapping("/setting")
public String process(@ModelAttribute("file") FileUploadForm file, RedirectAttribute redirectAttribute) {

  //ファイルが空でなく、画像形式ファイルでない場合
  if (!file.getUploadedFile().isEmpty() && !iResizer.isImageFileByImageIO(file.getUploadedFile())) {
    //エラーメッセージと共にリダイレクトする
    redirectAttributes.addFlashAttribute("errorMsg", "追加されたファイルは画像ではありません");
    return "redirect:/setting?setting";
  }
  
  //ファイルが空でなく、かつ画像形式ファイルの場合
  if (!file.getUploadedFile().isEmpty()) {
  // アイコン画像アップロード・リサイズ
    String iconStr = iResizer.uploadImage(response, file.getUploadedFile());
    user.setIcon(iconStr);
  }
  
  //ファイルが空の場合は、何も処理をしない
		
  uService.updateSetting(user);
}

 
 

3 ファイル形式が指定されたもの(画像形式)か
 
この部分については、こちらのページに非常に助けられました。
【Java】画像ファイルのチェック方法 - rm /blog
 
Javaでのファイル形式判定には、色んな選択肢があるようなのですが、画像リサイズ機能の方でImageIOを使用していたこともあり、今回はImageIOを使う方法でやることにしました。

// ファイルが画像なのか判定
public boolean isImageFileByImageIO(MultipartFile file) {
  
  try {
    // MultipartFileをFile形式に変換
    File convFile = new File(file.getOriginalFilename());
    // 拡張子を除いたファイル名を取得
    convFile.createNewFile();
    FileOutputStream fos = new FileOutputStream(convFile);
    fos.write(file.getBytes());
    fos.close();

    // ImageIOで、ファイルを読み込み
    if (convFile != null && convFile.isFile()) {
    BufferedImage bi = ImageIO.read(convFile);

      // 引数に渡したFileが画像ファイル以外の場合、BufferedImageがnullで返ってくる。
      if (bi != null) {
        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }

  } catch (IOException e) {
    throw new RuntimeException("Error uploading file.", e);
  }
}

BufferedImage bi = ImageIO.read(convFile);

こちらのコード
File型のインスタンスを引数にImageIOのreadメソッドを実行すると、結果がBufferedImage型で返ってくるのですが、引数のFileが画像形式以外だと、BufferedImageがnullになるそうなんです。
nullか否かで画像か否かが判断できるというわけみたい。



4 ファイルサイズが大きすぎないか
 
これに関しては非常にシンプルでした。
application.propertiesに以下のコードを追加するだけ。

//任意のファイルサイズ
spring.servlet.multipart.max-file-size=20MB




5 参考