RestControllerAdviceについて

エキサイト株式会社の中尾です。

SpringBootでexceptionが発生したとき、特定のエラーレスポンスで返す方法を記載します。

以下、コードになります。

@RestControllerAdvice
@Slf4j
public class ExceptionController {
    @ExceptionHandler({BadRequestException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String handleBindException(Exception exception) {
        this.writeLog(exception.getStackTrace());
        return exception.getMessage();
    }

    @ExceptionHandler({NoHandlerFoundException.class})
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String handleNotFoundException(Exception exception) {
        this.writeLog(exception.getStackTrace());
        return "404 Not Found";
    }

    private void writeLog(StackTraceElement[] stackTraceElements){
        Arrays.stream(stackTraceElements)
                .limit(10L)
                .forEach(e -> log.error(e.toString()));
    }
}
public class BadRequestException extends RuntimeException {
    public BadRequestException(String s) {
        super(s);
    }
}
spring:
  mvc:
    throw-exception-if-no-handler-found: true
  resources:
    add-mappings: false

解説します。

RestControllerAdviceはRestControllerと違ってGetMapping/PostMappingとかは記載せず、ExceptionHandlerで該当のExceptionが発生したときResponseStatusを返します、

spring.pleiades.io

動作検証

shogo.nakao@localhost: $ curl http://localhost:8080                                                                                     [/Users/shogo.nakao]
XXXX must not be empty

404の場合、springの設定ファイルにthrow-exception-if-no-handler-found: trueとadd-mappings: falseをプロパティファイルに設定した上でRestControllerAdviceに追加してください。

shogo.nakao@localhost: $ curl http://localhost:8080/aaa                                                                                                         [/Users/shogo.nakao]
404 Not Found

うまくいきました。

なお、以下のようにExceptionHandlerになにも指定しない場合、全てのエラーをキャッチすることができます。

    @ExceptionHandler
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String handleNotFoundException(Exception exception) {
        this.writeLog(exception.getStackTrace());
        return "all Exception catch";
    }

RestControllerAdviceには関係ありませんが、writeLogにstackTraceのエラーを10行ぐらいまで出力する設定になります。

        Arrays.stream(stackTraceElements)
                .limit(10L)
                .forEach(e -> log.error(e.toString()));