Spring Boot 基本

Spring Boot上でControllerAdviceアノテーションを利用したエラー処理を実装してみた

発生したエラー種類に応じたエラー処理を実装するには、ControllerAdviceアノテーションを適用したクラス内で、引数に例外クラスを指定したExceptionHandlerアノテーションを付与したメソッドを利用することで簡単に行える。

今回は、Spring Boot上でControllerAdviceアノテーションを利用したエラー処理を実装してみたので、そのサンプルプログラムを共有する。

前提条件

下記記事の実装が完了していること

IntelliJ IDEA上でGradleを使ってWeb画面のSpring Bootプロジェクトを作成してみたSpring Bootのプロジェクトを新規作成を「IntelliJ IDEA」のメニューから実施しようとしたところ、無料の「Commun...

サンプルプログラムの作成

作成したサンプルプログラムの構成は以下の通り。
サンプルプログラムの構成
なお、上記の赤枠は、前提条件のプログラムから変更したプログラムである。

ControllerAdviceアノテーションを適用したクラスの実装内容は以下の通りで、NullPointerExceptionが発生した場合、FileNotFoundExceptionが発生した場合、それ以外の例外が発生した場合それぞれで異なる例外処理を実施している。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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";
}
}
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"; } }
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";
    }
}



また、コントローラクラスの内容は以下の通り。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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が発生しました");
}
}
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が発生しました"); } }
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ファイルの内容は以下の通り。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!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>
<!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>
<!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>
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>error page</title>
</head>
<body>
   デフォルトのエラー画面に遷移しました。
</body>
</html>
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>error page</title> </head> <body>    デフォルトのエラー画面に遷移しました。 </body> </html>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>error page</title>
</head>
<body>
   デフォルトのエラー画面に遷移しました。
</body>
</html>
ウズウズカレッジJavaコースはわかりやすい動画教材と充実した就業サポートで優良企業を目指せるプログラミングスクールだったJavaは、世界中で広く使われていて、現在の需要が高く将来性もある開発言語になります。 https://www.acrovision....
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!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>
<!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>
<!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>
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!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>
<!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>
<!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を発生させます」ボタンを押下
サンプルプログラムの実行結果_1_1

2) 以下のように、デフォルトのエラー画面(error.html)が表示されることが確認できる
サンプルプログラムの実行結果_1_2

3) 以下の画面で「FileNotFoundExceptionを発生させます」ボタンを押下
サンプルプログラムの実行結果_1_3

4) 以下のように、デフォルトのエラー画面(error.html)が表示されることが確認できる
サンプルプログラムの実行結果_1_4

5) 以下の画面で「上記以外の例外を発生させます」ボタンを押下
サンプルプログラムの実行結果_1_5

6) 以下のように、デフォルトのエラー画面(error.html)が表示されることが確認できる
サンプルプログラムの実行結果_1_6

また、DemoControllerAdviceクラスを利用した場合の実行結果は、以下の通りで、発生したエラー種類に応じたエラー画面が表示される。

1) Spring Bootアプリケーションを起動し、「http://(サーバー名):(ポート番号)/」とアクセスすると、以下の画面が表示されるので、「NullPointerExceptionを発生させます」ボタンを押下
サンプルプログラムの実行結果_2_1

2) 以下のように、NullPointerExceptionが発生した場合のエラー画面(error_null.html)が表示されることが確認できる
サンプルプログラムの実行結果_2_2

3) 以下の画面で「FileNotFoundExceptionを発生させます」ボタンを押下
サンプルプログラムの実行結果_2_3

4) 以下のように、ファイルが見つからなかった場合のエラー画面(error_no_file.html)が表示されることが確認できる
サンプルプログラムの実行結果_2_4

5) 以下の画面で「上記以外の例外を発生させます」ボタンを押下
サンプルプログラムの実行結果_2_5

6) 以下のように、デフォルトのエラー画面(error.html)が表示されることが確認できる
サンプルプログラムの実行結果_2_6

要点まとめ

  • ControllerAdviceアノテーションを適用したクラス内で、引数に例外クラスを指定したExceptionHandlerアノテーションを付与したメソッドを利用すると、発生したエラー種類に応じたエラー処理を実装することができる。