0
0

More than 1 year has passed since last update.

SpringBoot で共通エラーハンドリング 【@RestControllerAdvise】

Posted at

はじめに

ついつい、個人で開発していると正常系の処理ばかり書いてエラーハンドリングの知識が身につかないと感じたので
今回はSpringBootでエラーハンドリングの実装に挑戦してみた。

今回はモノシリックなアプリではなく、RestApi形式で例外が発生した際にはエラー情報を格納したレスポンスを返す。

環境

言語: Java SDK 1.8
FW: Springboot 2.5
IDE: Intellij Idea

実装

通常の処理を行うコントローラを実装

下記実装では /{bloodType} にリクエストを投げた際に bloodType
メソッド isBloodType で血液型なのか判定しています。
もし血液型[ A, B, AB, O ]に当てはまらない場合、独自に実装したエラークラス BadBloodTypeException を呼ぶ。

main.java

package com.example.demo.controller;

import com.example.demo.common.BadBloodTypeException;
import com.example.demo.model.Person;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@RestController
public class SampleController {
    @GetMapping(value = "/{bloodType}")
    public ResponseEntity<Object> hello(@PathVariable String bloodType) {
        Person p = new Person();
        p.setFirstName("first");
        p.setMiddleName("middle");
        p.setLastName("last");
        p.setAge(24);
        boolean isBoodType = isBloodType(bloodType);

        if (isBoodType) {
            p.setBloodType(bloodType);
        }
        return ResponseEntity.status(HttpStatus.OK).body(p);
    }

    private boolean isBloodType(String bloodType) throws BadBloodTypeException{
        List<String> ageList = new ArrayList<String>(Arrays.asList("A","B","AB","O"));
        if (!ageList.contains(bloodType)) {
            throw new BadBloodTypeException("BadBloodTypeExceptionが発生しました");
        }
        return true;
    }
}

BadBloodTypeException 実装部分

単純に非検査例外を拡張して引数に渡されたメッセージをセットするだけです。

BadBloodTypeException.java
package com.example.demo.common;

public class BadBloodTypeException extends RuntimeException {
    public BadBloodTypeException(String message) {
        super(message);
    }
}

RestControllerAdvice 実装部分

このクラスを実装することにより処理中に発生したエラークラスに応じて共通の処理を格納しておくことができます。
下記実装部分では先ほど紹介した独自のエラークラス BadBloodTypeException が処理中で発生した際に自動で呼び出される。

上記コントローラの処理を振り返るとURLパラメータで渡された血液型が[ A, B, AB, O ]に当てはまらない場合、独自に実装したエラークラス BadBloodTypeException を呼び出します。その際、自動的に下記メソッドが呼び出されます。

※バッドリクエスト ステータスとbodyにメッセージ「不正なリクエストです。」を返します。

SampleControllerAdvise.java
package com.example.demo.controller;

import com.example.demo.common.BadBloodTypeException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class SampleControllerAdvise {

    @ExceptionHandler({BadBloodTypeException.class})  //  独自例外
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<Object> handleBadBloodTypeException(BadBloodTypeException e) {
        return new ResponseEntity<>("不正なリクエストです。", HttpStatus.BAD_REQUEST);
    }
}

画面上で確認

http://localhost:8080/A でアクセス

スクリーンショット 2021-09-26 11.13.47.png

http://localhost:8080/AAA でアクセス

スクリーンショット 2021-09-26 11.15.00.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0