はじめに
ついつい、個人で開発していると正常系の処理ばかり書いてエラーハンドリングの知識が身につかないと感じたので
今回はSpringBootでエラーハンドリングの実装に挑戦してみた。
今回はモノシリックなアプリではなく、RestApi形式で例外が発生した際にはエラー情報を格納したレスポンスを返す。
環境
言語: Java SDK 1.8
FW: Springboot 2.5
IDE: Intellij Idea
実装
通常の処理を行うコントローラを実装
下記実装では /{bloodType}
にリクエストを投げた際に bloodType
を
メソッド isBloodType
で血液型なのか判定しています。
もし血液型[ A, B, AB, O ]に当てはまらない場合、独自に実装したエラークラス BadBloodTypeException
を呼ぶ。
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 実装部分
単純に非検査例外を拡張して引数に渡されたメッセージをセットするだけです。
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にメッセージ「不正なリクエストです。」を返します。
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 でアクセス