기본 콘텐츠로 건너뛰기

라벨이 spring-mvc인 게시물 표시

스프링 MVC 응답 처리 이해하기: `@ResponseBody`, `ResponseEntity`, 그리고 뷰 반환의 차이

스프링 MVC 응답 처리 이해하기: @ResponseBody , ResponseEntity , 그리고 뷰 반환의 차이 스프링 MVC에서 컨트롤러 메서드는 결국 값을 return 합니다. 그런데 같은 return 이어도 어떤 경우에는 JSON이 내려가고, 어떤 경우에는 템플릿이 렌더링됩니다. 예를 들어 return "users/detail"; 는 화면 이름처럼 동작할 수도 있고, 응답 본문에 문자열 그대로 기록될 수도 있습니다. 이 차이는 자바 문법이 아니라 스프링 MVC의 반환값 해석 방식에서 생깁니다. 핵심은 컨트롤러가 무엇을 반환했는지가 아니라, 스프링이 그 반환값을 어떤 의미로 받아들이는지입니다. @ResponseBody 가 붙어 있는지, ResponseEntity<T> 를 반환하는지, 일반 @Controller 인지에 따라 내부 처리 경로가 달라집니다. 왜 같은 return 문인데 결과가 달라질까 가장 먼저 정리할 기준은 이것입니다. @ResponseBody 가 있으면 반환값은 HTTP 응답 본문으로 처리됩니다. ResponseEntity<T> 를 반환하면 응답 본문, 상태 코드, 헤더까지 함께 처리됩니다. 위 조건이 없고 @Controller 에서 String 을 반환하면 보통 뷰 이름으로 해석됩니다. 즉, 아래 두 코드는 문법은 비슷하지만 의미가 완전히 다릅니다. @Controller public class PageController { @GetMapping("/hello-page") public String hello() { return "hello"; } } 이 경우 "hello" 는 응답 문자열이 아니라 뷰 이름입니다. 스프링은 hello.html , hello.jsp 같은 실제 뷰를 찾으려 합니다. 반대로 다음 코드는 "hello" 를 응답 본문에 직접 씁니다. @Co...

Spring MVC에서 `@ExceptionHandler`를 제대로 쓰는 방법: 예외 흐름부터 전역 처리까지

Spring MVC에서 @ExceptionHandler 를 제대로 쓰는 방법: 예외 흐름부터 전역 처리까지 Spring MVC에서 예외 처리는 부가 기능이 아니라 API 설계의 일부입니다. 같은 실패 상황인데 어떤 엔드포인트는 400을 주고, 어떤 곳은 500을 주고, 어떤 응답은 메시지 형식조차 다르다면 클라이언트 코드도 복잡해지고 운영 중 원인 파악도 어려워집니다. @ExceptionHandler 는 이런 혼란을 줄이기 위한 핵심 도구입니다. 컨트롤러 실행 과정에서 발생한 예외를 잡아, 애플리케이션이 의도한 HTTP 상태 코드와 응답 본문으로 바꿔 주는 역할을 합니다. 단순히 예외를 숨기는 기능이 아니라, 예외를 API 계약에 맞는 응답으로 번역하는 장치라고 이해하면 훨씬 실무적입니다. 이 글에서는 @ExceptionHandler 가 정확히 어디서 동작하는지, @ControllerAdvice 와는 어떻게 역할을 나누는지, 그리고 실제로 어떤 응답 구조를 만들어야 유지보수가 쉬운지까지 한 번에 정리해보겠습니다. 왜 컨트롤러 예외 처리를 따로 설계해야 할까 예외는 없어지지 않습니다. 잘못된 요청 본문, 존재하지 않는 리소스, 현재 상태에서는 허용되지 않는 비즈니스 요청, 예상하지 못한 런타임 오류는 서비스가 살아 있는 한 계속 발생합니다. 중요한 것은 예외 발생 자체가 아니라, 그 예외가 어떤 HTTP 응답으로 변환되느냐입니다. 예외 처리를 설계하지 않으면 보통 다음 문제가 나타납니다. 사용자 입력 오류와 서버 내부 오류가 모두 500으로 보입니다. 프론트엔드가 엔드포인트마다 다른 실패 형식을 처리해야 합니다. 컨트롤러마다 try-catch 가 늘어나서 비즈니스 로직이 흐려집니다. 운영 로그에는 스택 트레이스만 남고, 클라이언트에게는 맥락 없는 오류 메시지만 전달됩니다. 실무에서는 예외를 “없애는 것”보다 “의미 있게 분류하는 것”이 더 중요합니다. 예를 들어 리소스 없음은 404, 요청 값 오류는 400, 상태 충돌은 409, 미처 고...