@ControllerAdvice와 @RestControllerAdvice의 차이점은 무엇인가요?
Source: Dev.to
Spring Boot에서 @ControllerAdvice와 @RestControllerAdvice의 차이를 명확한 설명과 엔드‑투‑엔드 Java 예제로 배워보세요.
소개
Spring Boot를 사용하여 두 개의 애플리케이션을 만든다고 상상해 보세요.
- 전통적인 웹 애플리케이션 – 브라우저에 HTML 페이지를 표시합니다.
- REST API – 모바일 앱이나 React와 같은 프런트엔드 프레임워크에서 사용됩니다.
이제 뭔가 잘못되었다고 가정해 보세요—예를 들어 사용자를 찾을 수 없거나 잘못된 요청이 전송된 경우.
모든 컨트롤러 내부에서 오류를 처리하고 싶으신가요? 물론 아니죠.
Spring은 @ControllerAdvice와 @RestControllerAdvice를 사용하여 오류를 전역적으로 처리하는 깔끔한 방법을 제공합니다.
초보자들이 자주 묻는 질문:
- 이 두 애노테이션은 동일한가요?
- 언제 어떤 것을 사용해야 하나요?
- REST API가 왜 다르게 동작하나요?
이 블로그에서는 명확한 개념과 엔드‑투‑엔드 실전 예제를 통해 @ControllerAdvice와 @RestControllerAdvice 차이점을 설명하고, 실제 Spring Boot 프로젝트에서 자신 있게 사용할 수 있도록 도와드립니다.
핵심 개념
@ControllerAdvice란?
@ControllerAdvice는 컨트롤러 전역에서 예외를 처리하기 위해 사용됩니다. 애플리케이션의 중앙 오류 처리기라고 생각하면 됩니다.
쉽게 이해하는 방법
각 컨트롤러가 개별적으로 오류를 처리하는 대신, 하나의 관리자가 모든 컨트롤러의 오류를 처리합니다.
핵심 포인트
@Controller와 함께 작동합니다 (MVC 애플리케이션)- 일반적으로 HTML 뷰 또는
ModelAndView를 반환합니다 - JSON을 반환하려면
@ResponseBody가 필요합니다
사용 사례
- 웹 애플리케이션
- 서버‑사이드 렌더링 페이지 (Thymeleaf, JSP)
- 커스텀 오류 페이지
@RestControllerAdvice란?
@RestControllerAdvice는 REST API에 특화되어 설계되었습니다. 기술적으로는 다음과 같습니다:
@ControllerAdvice + @ResponseBody
쉽게 이해하는 방법
오류 페이지를 반환하는 대신 구조화된 JSON 데이터를 반환합니다.
핵심 포인트
@RestController와 가장 잘 어울립니다- 응답을 자동으로 JSON으로 변환합니다
- 마이크로서비스와 API에 이상적입니다
사용 사례
- REST API
- 모바일 또는 프론트엔드 기반 애플리케이션
- 마이크로서비스 아키텍처
한눈에 보는 주요 차이점
| 특징 | @ControllerAdvice | @RestControllerAdvice |
|---|---|---|
| 애플리케이션 유형 | MVC / 웹 애플리케이션 | REST API |
| 기본 응답 | HTML / 뷰 | JSON |
@ResponseBody 필요 여부 | 예 | 아니오 |
| 가장 적합한 대상 | UI 기반 애플리케이션 | API 및 마이크로서비스 |
Source: …
End‑to‑End 코드 예제 (Java 21)
아래는 전체 작동 예제로, 각 어노테이션이 실제 시나리오에서 어떻게 사용되는지 보여줍니다.
예제 1: @ControllerAdvice를 사용한 End‑to‑End MVC 흐름
단계 1 – 사용자 정의 예외
public class PageNotFoundException extends RuntimeException {
public PageNotFoundException(String message) {
super(message);
}
}
단계 2 – MVC 컨트롤러
@Controller
@RequestMapping("/pages")
public class PageController {
@GetMapping("/{id}")
public String getPage(@PathVariable int id) {
if (id != 1) {
throw new PageNotFoundException("Page not found with id: " + id);
}
return "home"; // returns an HTML page
}
}
단계 3 – @ControllerAdvice를 사용한 전역 예외 처리기
@ControllerAdvice
public class GlobalMvcExceptionHandler {
@ExceptionHandler(PageNotFoundException.class)
public String handlePageNotFound(PageNotFoundException ex, Model model) {
model.addAttribute("errorMessage", ex.getMessage());
return "error"; // resolves to error.html
}
}
결과: 브라우저가 HTML 오류 페이지를 받게 됩니다 – 컨트롤러 코드는 깔끔하게 유지하면서 중앙집중식 오류 처리를 수행합니다.
예제 2: @RestControllerAdvice를 사용한 End‑to‑End REST API 흐름
단계 1 – 사용자 정의 예외
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
단계 2 – 오류 응답 모델
import java.time.LocalDateTime;
public record ErrorResponse(
int status,
String message,
LocalDateTime timestamp
) {}
단계 3 – REST 컨트롤러
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable Long id) {
if (!id.equals(1L)) {
throw new ResourceNotFoundException("User not found with id: " + id);
}
return "User found";
}
}
단계 4 – @RestControllerAdvice를 사용한 전역 예외 처리기
@RestControllerAdvice
public class GlobalRestExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity handleResourceNotFound(
ResourceNotFoundException ex) {
ErrorResponse response = new ErrorResponse(
HttpStatus.NOT_FOUND.value(),
ex.getMessage(),
LocalDateTime.now()
);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
}
}
결과 (JSON 응답):
{
"status": 404,
"message": "User not found with id: 2",
"timestamp": "2025-01-10T12:30:45"
}
모범 사례
- REST API에는
@RestControllerAdvice사용 – 자동 직렬화(예: JSON)를 보장하고@ResponseBody누락을 방지합니다. - MVC 애플리케이션에는
@ControllerAdvice만 사용 – 뷰나 템플릿을 반환해야 할 때 이상적입니다. - 일관된 오류 응답 구조를 생성 – 프론트엔드 팀과 API 사용자가 오류를 일관되게 처리할 수 있도록 돕습니다.
- 올바른 HTTP 상태 코드를 매핑 – 각 오류 상황에 맞게
400,404,401,500등을 적절히 사용합니다. - 일반
Exception처리보다 먼저 구체적인 예외를 처리 –Exception.class에 fallback하기 전에 항상 특정 예외를 먼저 처리합니다.
Common Mistakes to Avoid
- ❌
@ResponseBody없이 REST API에서@ControllerAdvice사용 - ❌ REST API에서 HTML 오류 페이지 반환
- ❌ 예외를 개별 컨트롤러에서 처리하고 중앙에서 관리하지 않음
- ❌ API 응답에 스택 트레이스나 내부 세부 정보 노출
결론
@ControllerAdvice와 @RestControllerAdvice의 차이는 애플리케이션이 오류를 전달하는 방식에 있습니다:
- **
@ControllerAdvice**는 HTML을 반환하는 전통적인 웹 애플리케이션에 사용합니다. - **
@RestControllerAdvice**는 JSON(또는 기타 본문 기반 포맷)을 반환하는 REST API에 사용합니다.
두 어노테이션 모두 중앙 집중식이며 깔끔하고 확장 가능한 예외 처리를 제공합니다. 이 차이를 이해하면 실제 프로젝트든 면접이든 Spring Boot 애플리케이션을 더 쉽게 유지 보수하고 보다 전문적으로 만들 수 있습니다.
