
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. [도서 쇼핑몰] 예외 처리 페이지 만들기
- @ResponseStatus로 예외 처리하기
- @ExceptionHandler로 예외 처리하기
- @ControllerAdvice로 예외 처리하기
출처 : 송미영, 『 스프링부트 완전정복: 개념부터 실정 프로젝트까지 』길벗캠퍼스 (2024).
'DEVELOPMENT > Spring' 카테고리의 다른 글
| [스프링부트 완전정복] 13. RESTful 웹 서비스 (0) | 2025.12.30 |
|---|---|
| [스프링부트 완전정복] 12. 로그 기록 (0) | 2025.12.30 |
| [스프링부트 완전정복] 10장. 시큐리티 처리 (0) | 2025.12.16 |
| [스프링부트 완전정복] 9. 유효성 검사 (0) | 2025.11.21 |
| [스프링부트 완전정복] 8. 다국어 처리 (1) | 2025.11.15 |