본문 바로가기

더 나은 엔지니어가 되기 위해/지금은 안쓰는 자바

[스프링 부트 개념과 활용] 웹 MVC 설정 3. ExceptionHandler

인프런에서 백기선님의 스프링부트 개념과 활용 강의를 듣고, 개인적으로 공부하며 핵심만 정리한 글입니다.

스프링 MVC의 ExceptionHandler

이번에는 Exception error 를 처리하는 ExceptionHandler 에 대해 알아본다.

먼저 예외 상황을 정의할 클래스 SampleExcepition 를 만든다.

public class SampleException extends RuntimeException {
}

다음으로, 에러의 정보를 담을 AppError 클래스를 정의하자.

public class AppError {
  private String message;
  private String reason;

  public String getMessage() {
    return message;
  }
  ... 
  (getter and setter)
}

이제 Controller 안에서 예외상황을 일으키고, 이를 처리하는 코드를 작성하자.

@Controller
public class SampleController {

  @GetMapping("/exception")
  public String hello() {
    throw new SampleException();
  }

  @ExceptionHandler(SampleException.class)
  public @ResponseBody AppError sampleError(SampleException e) {
    AppError appError = new AppError();
    appError.setMessage("error message");
    appError.setReason("error reason");

    return appError;
  }
}

위 코드를 살펴보면,

  • throw new SampleException() 로 예외처리 해달라는 요청이 있고
  • @ExceptionHandler(SampleException.class) 가 이 요청을 받는다.
  • 그리고 이 Exception 상황일 때, 어떻게 처리할 것인지에 대한 메쏘드 sampleError() 가 정의되어 있다.

여기서는 AppError 객체를 바로 반환하지만, 현업에서는 ResponseEntity<AppError> 와 같이 ResponseEntitiy 로 에러 객체를 감싸서 내보낸다고 한다.

또 전역에 사용할 ExceptionHandler 는 @ControllerAdvice 를 붙힌 클래스 안에다가 정의하면 된다.
예를 들면 다음과 같은 모양이다.

@ControllerAdvice
public class ExceptionController {

  @ExceptionHandler(SampleException.class)
  public @ResponseBody AppError sampleError1(SampleException e) {
    ...
    return appError;
  }

  @ExceptionHandler(SampleException.class)
  public @ResponseBody AppError sampleError2(SampleException e) {
    ...
    return appError;
  }

  ...
}

스프링 부트의 ExceptionHandler

org.springframework.boot.autoconfigure.web.servlet.error 의 패키지로 가면 BasicErrorController 가 대략 다음과 같이 정의되어 있다.

@Controller
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class BasicErrorController extends AbstractErrorController {
  private final ErrorProperties errorProperties;

  public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties) {
    this(errorAttributes, errorProperties, Collections.emptyList());
  }

  ...
}

ExceptionHandler 를 커스터마이징 하고 싶다면, BasicErrorController 를 상속받거나 AbstractErrorController 를 인터페이스로 구현하면 된다.

커스텀 에러페이지

resources/static/error 내에 에러코드의 이름으로 html 파일을 만들어주면, 해당 에러코드 발생 시 해당 페이지로 연결해준다.
예를 들어, 404 페이지나 500번대 에러 페이지는 다음과 같이 정의해주면 된다.

  • resources/static/error/404.html
  • resources/static/error/5xx.html