発生したエラー種類に応じたエラー処理を実装するには、ControllerAdviceアノテーションを適用したクラス内で、引数に例外クラスを指定したExceptionHandlerアノテーションを付与したメソッドを利用することで簡単に行える。
今回は、Spring Boot上でControllerAdviceアノテーションを利用したエラー処理を実装してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装が完了していること
サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。
なお、上記の赤枠は、前提条件のプログラムから変更したプログラムである。
ControllerAdviceアノテーションを適用したクラスの実装内容は以下の通りで、NullPointerExceptionが発生した場合、FileNotFoundExceptionが発生した場合、それ以外の例外が発生した場合それぞれで異なる例外処理を実施している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | package com.example.demo; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import java.io.FileNotFoundException; @ControllerAdvice public class DemoControllerAdvice { /** * NullPointerExceptionが発生した場合のエラー処理を行う * @param exception 発生した例外 * @return NullPointerExceptionが発生した場合のエラー画面 */ @ExceptionHandler(NullPointerException.class) public String nullError(NullPointerException exception, Model model) { model.addAttribute("errMsg", exception.getMessage()); return "error_null"; } /** * FileNotFoundExceptionが発生した場合のエラー処理を行う * @param exception 発生した例外 * @return FileNotFoundExceptionが発生した場合のエラー画面 */ @ExceptionHandler(FileNotFoundException.class) public String noFileError(FileNotFoundException exception, Model model) { model.addAttribute("errMsg", exception.getMessage()); return "error_no_file"; } /** * 上記以外の例外が発生した場合のエラー処理を行う * @param exception 発生した例外 * @return デフォルトのエラー画面 */ @ExceptionHandler(Exception.class) public String occurOtherException(Exception exception){ return "error"; } } |
また、コントローラクラスの内容は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | package com.example.demo; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import java.io.FileNotFoundException; import java.io.IOException; @Controller public class DemoController { /** * 初期表示画面に遷移する * @return 初期表示画面へのパス */ @GetMapping("/") public String index(){ return "index"; } /** * NullPointerExceptionを発生させる * @return 初期表示画面へのパス */ @PostMapping("/occurNullPointerException") public String occurNullPointerException(){ throw new NullPointerException("NullPointerExceptionが発生しました"); } /** * FileNotFoundExceptionを発生させる * @return 初期表示画面へのパス * @throws FileNotFoundException */ @PostMapping("/occurFileNotFoundException") public String occurFileNotFoundException() throws FileNotFoundException{ throw new FileNotFoundException("FileNotFoundExceptionが発生しました"); } /** * IOExceptionを発生させる * @return 初期表示画面へのパス * @throws Exception */ @PostMapping("/occurOtherException") public String occurOtherException() throws IOException{ throw new IOException("IOExceptionが発生しました"); } } |
さらに、各HTMLファイルの内容は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <!DOCTYPE html> <html lang="ja" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>index page</title> </head> <body> 初期表示画面に遷移しました。<br/><br/> <form method="post" th:action="@{/occurNullPointerException}"> <button type="submit">NullPointerExceptionを発生させます</button> </form> <br/><br/> <form method="post" th:action="@{/occurFileNotFoundException}"> <button type="submit">FileNotFoundExceptionを発生させます</button> </form> <br/><br/> <form method="post" th:action="@{/occurOtherException}"> <button type="submit">上記以外の例外を発生させます</button> </form> </body> </html> |
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>error page</title> </head> <body> デフォルトのエラー画面に遷移しました。 </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 | <!DOCTYPE html> <html lang="ja" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>error page</title> </head> <body> 予期せぬ例外が発生しました。 <br/><br/> 例外: <span th:text="${errMsg}"></span> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 | <!DOCTYPE html> <html lang="ja" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>error page</title> </head> <body> ファイルが見つかりませんでした。 <br/><br/> 例外: <span th:text="${errMsg}"></span> </body> </html> |
その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-controller-advice-error/demo
サンプルプログラムの実行結果
DemoControllerAdviceクラスを利用していない場合の実行結果は、以下の通りで、全てデフォルトのエラー画面が表示される。
1) Spring Bootアプリケーションを起動し、「http://(サーバー名):(ポート番号)/」とアクセスすると、以下の画面が表示されるので、「NullPointerExceptionを発生させます」ボタンを押下
2) 以下のように、デフォルトのエラー画面(error.html)が表示されることが確認できる
3) 以下の画面で「FileNotFoundExceptionを発生させます」ボタンを押下
4) 以下のように、デフォルトのエラー画面(error.html)が表示されることが確認できる
5) 以下の画面で「上記以外の例外を発生させます」ボタンを押下
6) 以下のように、デフォルトのエラー画面(error.html)が表示されることが確認できる
また、DemoControllerAdviceクラスを利用した場合の実行結果は、以下の通りで、発生したエラー種類に応じたエラー画面が表示される。
1) Spring Bootアプリケーションを起動し、「http://(サーバー名):(ポート番号)/」とアクセスすると、以下の画面が表示されるので、「NullPointerExceptionを発生させます」ボタンを押下
2) 以下のように、NullPointerExceptionが発生した場合のエラー画面(error_null.html)が表示されることが確認できる
3) 以下の画面で「FileNotFoundExceptionを発生させます」ボタンを押下
4) 以下のように、ファイルが見つからなかった場合のエラー画面(error_no_file.html)が表示されることが確認できる
5) 以下の画面で「上記以外の例外を発生させます」ボタンを押下
6) 以下のように、デフォルトのエラー画面(error.html)が表示されることが確認できる
要点まとめ
- ControllerAdviceアノテーションを適用したクラス内で、引数に例外クラスを指定したExceptionHandlerアノテーションを付与したメソッドを利用すると、発生したエラー種類に応じたエラー処理を実装することができる。