DEVELOPMENT/Spring

[스프링부트 완전정복] 11. 예외 처리

Tiny Commit 2025. 12. 30. 09:47

 

 

 

 

 

 

1. 예외 처리의 개요

스프링 부트 애플리케이션을 개발하다 보면 웹 요청 처리 중 다양한 예외가 발생합니다. 예외가 발생했을 때 사용자에게 단순히 에러 페이지를 보여주는 것이 아니라, 적절한 HTTP 상태 코드메시지를 전달하는 것이 중요합니다.

1.1 예외 처리

  • 프로그램 실행 중 문제가 발생했을 때, 해당 처리를 중단하고 비정상 종료를 막기 위해 별도의 처리를 하는 것을 의미합니다. 웹 애플리케이션에서는 에러 발생 시 사용자에게 적절한 응답을 주는 것이 핵심입니다.

1.2 예외 처리 방법

  • 웹 요청에 따라 컨트롤러의 요청 처리 ㅁ서드가 실행되는 중에 발생한 예외를 처리할 수 있는 유용한 애너페이션
애너테이션 설명
@ResponseStatus 예외를 특정 HTTP 상태 코드와 매핑하여 응답
@ExceptionHandler 특정 컨트롤러 내에서 발생하는 에러를 직접 구체화하여 처리
@ControllerAdvice 여러 컨트롤러에서 발생하는 공통 예외를 한곳에서 모아 처리

 

 

 

 

2. @ResponseStatus 를 이용한 HTTP 상태 코드 기반 예외 처리

2.1 HTTP 상태 코드

  • 서버가 정상 처리되었는지 오류가 발생했는지를 알려주는 정보를 담고 있는것
상태 코드 상숫값 설명
400 BAD_REQUEST 잘못된 요청일 때 사용
401 UNAUTHORIZED 클라이언트 인증 문제 발생 시 사용
403 FORBIDDEN 접근 권한이 없을 때 사용
404 NOT_FOUND 요청한 리소스가 없을 때 사용
405 METHOD_NOT_ALLOWED 지원하지 않는 HTTP 메서드 사용 시
500 INTERNAL_SERVER_ERROR 서버 내부 로직 오류(API 오류) 발생 시

 

 

2.2 @ResponseStatus로 예외 처리

  • 컨트롤러 메서드에 직접 사용: 특정 메서드 실행 시 예외가 발생하면 지정된 코드를 반환합니다.
  • 사용자 정의 예외 클래스에 사용: 특정 예외 클래스가 던져질 때마다 지정된 코드를 반환합니다. (권장)
// [코드 예시 1] 메서드에 선언하는 경우

@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "요청에 실패했습니다.")
@GetMapping("/exam01")
public void requestMethod() {
    // 예외 발생 시 400 Bad Request 반환
}

 

// [코드 예시 2] 예외 클래스에 선언하는 경우
// 사용자 정의 예외를 만들고 어노테이션을 붙여두면, 어디서든 이 예외가 발생할 때 동일한 응답을 보낼 수 있습니다.

@GetMapping("/exam02")
public void requestMethod() throws Exception {
    // 예외 발생 시 
}



@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "찾을 수 없습니다")
public class UserException extends RuntimeException {
    public UserException(String message) {
        super(message);
    }
}

 

 

 

 

 

3. @ExceptionHandler  를 이용한 HTTP 상태 코드 기반 예외 처리

3.1 @ExceptionHandler: 컨트롤러 기반 예외 처리

@ExceptionHandler는 특정 컨트롤러 클래스 내에서 발생하는 예외를 직접 잡아서 처리할 때 사용합니다.

  • 특징: 발생한 예외 정보를 직접 얻을 수 있고, 에러 전용 뷰 페이지로 이동시키거나 상세 메시지를 사용자에게 응답할 수 있습니다.
  • 사용법: 컨트롤러 내부에 별도의 메서드를 만들고 잡고 싶은 예외 클래스를 지정합니다.
// [코드 예시] 컨트롤러 내 예외 처리

@Controller
public class Example03Controller {

    @GetMapping("/exam03")
    public void requestMethod() {
        throw new UserException("UserException 메시지입니다");
    }

    // UserException 발생 시 이 메서드가 실행됨
    @ExceptionHandler(UserException.class)
    public String handleException(UserException ex, Model model) {
        model.addAttribute("data1", ex.getMessage());
        model.addAttribute("data2", ex);
        return "viewPage"; // 에러 전용 뷰 페이지 반환
    }
}

 

 

 

 

 

4. @ControllerAdvice 를 이용한 HTTP 상태 코드 기반 예외 처리

4.1 @ControllerAdvice: 전역(Global) 예외 처리

애플리케이션 내의 여러 컨트롤러에서 발생하는 예외를 한곳에서 공통으로 처리하고 싶을 때 사용합니다. 이를 통해 각 컨트롤러마다 예외 처리 코드를 중복해서 작성할 필요가 없어집니다.

  • 범위 설정: basePackages 속성을 통해 특정 패키지 내의 컨트롤러만 관리하도록 설정할 수 있습니다.
  • 지원 기능: @ExceptionHandler뿐만 아니라 @ModelAttribute, @InitBinder가 선언된 메서드도 사용할 수 있습니다.

@ControllerAdvice 주요 속성

요소 타입 설명
annotations Class<? extends Annotation>[] 특정 애너테이션이 붙은 컨트롤러만 대상
basePackages String[] 지정한 패키지 및 하위 패키지 대상 (가장 많이 사용)
assignableTypes Class<?>[] 특정 클래스 타입의 컨트롤러 대상

 

// [코드 예시] 전역 예외 처리 클래스

@ControllerAdvice(basePackages={"com.springboot"})
public class GlobalException {

    @ExceptionHandler(RuntimeException.class)
    private String handleErrorMessage(Exception ex, Model model) {
        model.addAttribute("data1", "GlobalException 메시지입니다");
        model.addAttribute("data2", ex);
        return "viewPage";
    }
}

 

 

 

 

5. [도서 쇼핑몰] 예외 처리 페이지 만들기

  1. @ResponseStatus로 예외 처리하기
  2. @ExceptionHandler로 예외 처리하기
  3. @ControllerAdvice로 예외 처리하기

 

 

 


출처 : 송미영, 『 스프링부트 완전정복: 개념부터 실정 프로젝트까지 』길벗캠퍼스 (2024).