서비스 모듈 | ControllerAdvice

Faithful Dev·2025년 3월 12일

@ControllerAdviceSpring MVC에서 전역적으로 예외를 처리하거나, 컨트롤러에서 공통적으로 적용할 수 있는 기능을 정의할 때 사용하는 어노테이션이다. 이를 활용하면 개별 컨트롤러마다 중복된 예외 처리 로직을 작성할 필요 없이 중앙 집중적으로 예외 처리를 할 수 있다.

주요 기능

  • 전역 예외 처리 (@ExceptionHandler)
    특정 예외가 발생했을 때, 이를 공통적으로 처리하는 메서드를 정의할 수 있다.
  • 전역 바인딩 처리 (@InitBinder)
    컨트롤러에서 사용될 요청 파라미터에 대한 바인딩 설정을 미리 정의할 수 있다.
  • 전역 모델 속성 설정 (@ModelAttribute)
    모든 컨트롤러에서 공통적으로 사용할 모델 데이터를 설정할 수 있다.

예외 처리 예제

다음은 @ControllerAdvice를 사용하여 예외를 전역적으로 처리하는 방법이다.

기본적인 예외 처리

@RestControllerAdvice // @ControllerAdvice + @ResponseBody
public class GlobalExceptionHandler {

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map<String, String> handleIllegalArgumentException(IllegalArgumentException ex) {
        Map<String, String> errorResponse = new HashMap<>();
        errorResponse.put("error", ex.getMessage());
        return errorResponse;
    }
}
  • @RestControllerAdvice@ControllerAdvice@ResponseBody를 합친 것.
  • @ExceptionHandler(IllegalArgumentException.class): IllegalArgumentException 예외가 발생하면 이 메서드가 실행됨.
  • @ResponseStatus(HttpStatus.BAD_REQUEST): HTTP 상태 코드를 400 (Bad Request)로 설정.
  • 예외 메시지를 JSON 형식으로 반환.

여러 예외 처리

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String handleIllegalArgumentException(IllegalArgumentException ex) {
        return ex.getMessage();
    }

    @ExceptionHandler(NullPointerException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String handleNullPointerException(NullPointerException ex) {
        return "서버 내부 오류 발생";
    }
}
  • IllegalArgumentException은 400 오류를 반환하고,
  • NullPointerException이 발생하면 500 (Internal Server Error) 상태를 반환.

ResponseEntity 활용 예외 처리

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<Map<String, String>> handleRuntimeException(RuntimeException ex) {
        Map<String, String> errorResponse = new HashMap<>();
        errorResponse.put("error", ex.getMessage());
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
    }
}
  • ResponseEntity를 활용하면 HTTP 상태 코드와 응답 값을 유연하게 설정할 수 있음.

공통 모델 속성 설정

모든 컨트롤러에서 공통적으로 사용할 모델 속성을 정의할 수 있다.

@ControllerAdvice
public class GlobalControllerAdvice {

    @ModelAttribute("appName")
    public String getAppName() {
        return "My Spring Application";
    }
}
  • 모든 컨트롤러에서 appName이라는 속성을 사용할 수 있게 된다.

@InitBinder 사용 예제

@ControllerAdvice
public class GlobalBindingAdvice {

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                setValue(LocalDate.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            }
        });
    }
}
  • 모든 컨트롤러에서 LocalDate 파라미터가 들어올 때 "yyyy-MM-dd" 형식으로 변환되도록 설정.

정리

기능어노테이션설명
전역 예외 처리@ExceptionHandler특정 예외 발생 시 처리
전역 데이터 바인딩@InitBinder요청 데이터를 변환
전역 모델 속성 설정@ModelAttribute모든 컨트롤러에서 공통으로 사용할 데이터 설정

@ControllerAdvice를 사용하면 컨트롤러 코드의 중복을 줄이고, 예외 처리와 설정을 일괄적으로 관리할 수 있어 유지보수성이 향상된다.

profile
Turning Vision into Reality.

0개의 댓글