본문 바로가기
카테고리 없음

Spring Boot에서 에러 핸들링 종류와 방법

by 용용이아바이 2025. 2. 28.
728x90

Spring Boot에서는 다양한 방식으로 에러를 처리할 수 있습니다. 이 글에서는 Spring Boot에서 사용할 수 있는 대표적인 에러 핸들링 방법을 정리하고, 각각의 예제 코드를 제공하겠습니다.


✅ 1. Spring Boot에서 발생하는 주요 에러 종류

Spring Boot 애플리케이션에서 자주 발생하는 에러는 다음과 같습니다:

에러 코드 설명

400 (Bad Request) 잘못된 요청으로 인해 발생
401 (Unauthorized) 인증이 필요한 요청이나 인증 실패
403 (Forbidden) 권한이 없는 요청
404 (Not Found) 요청한 리소스를 찾을 수 없음
500 (Internal Server Error) 서버 내부 오류

✅ 2. @ExceptionHandler를 활용한 개별 예외 처리

개별적인 예외를 @ExceptionHandler를 사용하여 처리할 수 있습니다.

📌 예제 코드 - 특정 예외 처리

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {

    // 404 Not Found 예외 처리
    @ExceptionHandler(NoResourceFoundException.class)
    public String handleNotFoundError(HttpServletRequest request, Model model) {
        model.addAttribute("requestURI", request.getRequestURI());
        return "error/404";
    }

    // 500 Internal Server Error 예외 처리
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleServerError(HttpServletRequest request, Exception ex) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("서버 오류 발생: " + ex.getMessage());
    }
}

✅ NoResourceFoundException이 발생하면 error/404.html 페이지를 보여줌 ✅ Exception.class는 모든 예외를 처리하며, JSON 응답을 반환


✅ 3. @ControllerAdvice와 ErrorController를 함께 사용하기

📌 ErrorController를 활용하여 모든 오류 처리

ErrorController를 직접 구현하면 /error 경로를 처리할 수 있습니다.

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class CustomErrorController implements ErrorController {

    @RequestMapping("/error")
    public String handleError(HttpServletRequest request) {
        Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
        
        if (status != null) {
            int statusCode = Integer.parseInt(status.toString());
            if (statusCode == HttpStatus.NOT_FOUND.value()) {
                return "error/404";
            } else if (statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
                return "redirect:/";
            }
        }
        return "redirect:/";
    }
}

✅ 존재하지 않는 페이지(404)는 error/404.html을 보여줌 ✅ 500 오류는 / (메인 페이지)로 이동


✅ 4. application.properties에서 기본 오류 처리 설정 변경

Spring Boot 기본 오류 페이지(Whitelabel Error Page)를 비활성화하려면 다음 설정을 추가하면 됩니다.

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
server.error.whitelabel.enabled=false

# 설명:
# - spring.mvc.throw-exception-if-no-handler-found=true: 매핑되지 않은 요청이 들어오면 404 예외를 발생시킵니다.
# - spring.resources.add-mappings=false: 정적 리소스 매핑을 비활성화하여 Spring이 직접 리소스를 제공하지 않도록 설정합니다.
# - server.error.whitelabel.enabled=false: Spring Boot의 기본 오류 페이지(Whitelabel Error Page)를 비활성화합니다.

✅ 기본 Whitelabel Error Page를 제거하고, ErrorController에서 직접 처리 가능


✅ 5. REST API에서 글로벌 예외 처리

REST API에서는 모든 예외를 JSON 형태로 반환하도록 처리할 수 있습니다.

@RestControllerAdvice
public class ApiExceptionHandler {
    
    @ExceptionHandler(Exception.class)
    public ResponseEntity<Map<String, Object>> handleAllExceptions(Exception ex) {
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("error", "서버 오류 발생");
        errorResponse.put("message", ex.getMessage());
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
    }
}

✅ @RestControllerAdvice를 사용하면 모든 컨트롤러에서 발생하는 예외를 JSON으로 반환 가능


✅ 6. 에러 핸들링 흐름도

Spring Boot에서 발생하는 오류가 처리되는 흐름을 도식화하면 다음과 같습니다:

  1. 요청(Request): 클라이언트가 특정 URL로 요청을 보냄.
  2. 컨트롤러 매핑 확인: 요청이 매핑된 컨트롤러가 있는지 확인.
    1. 있다면 정상 처리됨.
    2. 없다면 404(Not Found) 오류 발생.
  3. 예외 발생 시 처리:
    1. @ExceptionHandler가 등록된 특정 예외라면 해당 핸들러에서 처리.
    2. @ControllerAdvice가 등록된 글로벌 핸들러에서 처리.
    3. 예외가 ErrorController로 전달됨.
  4. 응답(Response) 결정:
    1. HTML 페이지 요청: error/404.html과 같은 오류 페이지 렌더링.
    2. API 요청: ResponseEntity를 통해 JSON 응답 반환.
    3. 기본 처리 없는 경우: /error 경로로 이동하여 CustomErrorController에서 처리.
[ 요청 ]  →  [ 컨트롤러 확인 ] → (X) → [ 예외 발생 ] → [ (1) 컨트롤러의 @ExceptionHandler ] → [ (2) @ControllerAdvice ] → [ (3) ErrorController ] → [ 예외 최종 처리 ] 
 → [ 적절한 응답 반환 ]

✅ 7. 최종 정리

해결 방법 설명

@ExceptionHandler 특정 예외를 개별적으로 처리
@ControllerAdvice 전역 예외를 처리하고 오류 페이지로 이동
ErrorController /error 요청을 받아서 특정 페이지 또는 메인으로 리다이렉트
application.properties 설정 기본 오류 페이지(Whitelabel Error Page) 제거
@RestControllerAdvice REST API에서 JSON 기반 오류 응답

이제 Spring Boot에서 발생하는 다양한 에러를 효과적으로 핸들링할 수 있습니다! 🚀

추가 질문이 있으면 언제든지 댓글로 남겨주세요! 😊

728x90