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에서 발생하는 오류가 처리되는 흐름을 도식화하면 다음과 같습니다:
- 요청(Request): 클라이언트가 특정 URL로 요청을 보냄.
- 컨트롤러 매핑 확인: 요청이 매핑된 컨트롤러가 있는지 확인.
- 있다면 정상 처리됨.
- 없다면 404(Not Found) 오류 발생.
- 예외 발생 시 처리:
- @ExceptionHandler가 등록된 특정 예외라면 해당 핸들러에서 처리.
- @ControllerAdvice가 등록된 글로벌 핸들러에서 처리.
- 예외가 ErrorController로 전달됨.
- 응답(Response) 결정:
- HTML 페이지 요청: error/404.html과 같은 오류 페이지 렌더링.
- API 요청: ResponseEntity를 통해 JSON 응답 반환.
- 기본 처리 없는 경우: /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에서 발생하는 다양한 에러를 효과적으로 핸들링할 수 있습니다! 🚀
추가 질문이 있으면 언제든지 댓글로 남겨주세요! 😊