Springで自身の作成したエラークラスで例外処理をしてみます。
簡単なRestAPIのエラー処理をします。
概要
Springでは例外処理を共通で制御できるよう便利な機能があります。
Spring MVCが提供する「ResponseEntityExceptionHandler」クラスを継承することで実装可能です。(AOPと呼ばれる手法)
デフォルトで提供されるメソッドとしては、「サポートしていないHTTPメソッドが使用された場合に発生する例外」や「必須のリクエストパタメーターが設定されていない場合に発生する例外」等が用意されています。
今回はデフォルトで定義されていない例外処理の設定を記載していきます。
実装としては「id」をキーにデータを取得するAPIで、データが存在しなかった場合のエラー処理を実装したいと思います。

上記ツールは以下を使用しています。
https://itmaroblog.com/api-test-tool/
実装
エラー情報をつめるbean作成
エラー情報をつめるクラス作成します。
ステータスコードとエラーメッセージを設定します。
package sample.api.sample.error;
import java.io.Serializable;
public class ApiError implements Serializable {
private static final long serialVersionUID = 1L;
private int status;
private String message;
public ApiError(int status, String message) {
this.status = status;
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
独自例外クラス作成
独自の例外クラスを作成します。
「RuntimeException」クラスを継承します。
package sample.api.sample.error;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.http.HttpStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException{
private static final long serialVersionUID = 1L;
public NotFoundException(String message) {
super(message);
}
}
ハンドリングクラス作成
例外処理をするにあたって、ハンドリングするクラスを作成します。
package sample.api.sample.error;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@RestControllerAdvice
public class ApiExceptionHandler extends ResponseEntityExceptionHandler {
// 例外処理の全てのレスポンスをカスタマイズ
@Override
protected ResponseEntity<Object> handleExceptionInternal(
Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request
) {
ApiError apiError = new ApiError(status.value(), ex.getMessage());
return super.handleExceptionInternal(ex, apiError, headers, status, request);
}
// NotFoundExceprionクラスがthrowされた場合に実行
@ExceptionHandler(NotFoundException.class)
protected ResponseEntity<Object> handleResponseStatus(NotFoundException ex, WebRequest request) {
System.out.println("エラー制御");
return handleExceptionInternal(ex, null,null, HttpStatus.NOT_FOUND, request);
}
}
@RestControllerAdvice
共通的な例外処理を実装するために付けています。
RESTではない場合は「ControllerAdvice」となりエラー処理でModel(HTML)を返却することも可能です。
handleExceptionInternal
オーバーライドして、例外の共通処理を記載しています。
ステータスコードと、エラーメッセージを設定しています。
@ExceptionHandler(NotFoundException.class)
NotFoundExceptionクラスがthrowされた際に実行されるメソッドです。
実行クラス
実行クラスは以下のように記載しています。
エラーの際は「NotFoundException」クラスをthrowしています。
public SampleResource findById(int id) {
try {
return dao.findById(id);
} catch(IncorrectResultSizeDataAccessException e) {
String errorMessage = "対象データが存在しません";
throw new NotFoundException(errorMessage);
}
}
参考文献

