Spring Boot에서 @RestController로 들어온 HTTP 요청이 처리되어 응답으로 변환되는 전체 과정 + HTTP 메시지 컨버터가 동작하는 시점과 역할
Controller-Service-Repository 패턴에서
컨트롤러는 사용자 요청을 처리하고, 적절한 응답을 반환하는 역할을 한다.
컨트롤러는 HTTP 요청을 수신하고, 서비스 계층에 비즈니스 로직 수행을 요청한 후,
클라이언트에게 적절한 뷰(View) 또는 데이터(JSON 등) 응답을 반환한다.
이러한 역할을 수행하기 위해, 컨트롤러 클래스는 @Controller 어노테이션을 사용하여 정의할 수 있다.
@Controller 어노테이션은 주로 View를 반환하기 위해 사용된다.
반환된 값은 뷰의 이름으로 해석되며, 해당 뷰가 렌더링된다.
📌 @Controller 예시
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable Long id, Model model) {
// 로직 처리 후 model에 데이터 추가
model.addAttribute("user", "홍길동");
return "userView"; // 뷰 이름 반환
}
}
위 코드에서 컨트롤러는 GET /users/{id} 요청이 들어오면 userView.html과 같은 특정한 뷰를 보여줄 것이다.
@RestController는 뷰가 아니라 데이터를 반환할 때 사용한다.
그러면 반환 값을 뷰가 아니라 HTTP 응답 바디(본문)에 직접 넣어야 한다.
@RestController는 @Controller에
컨트롤러 메서드 반환 값을 바로 HTTP 응답 바디로 직렬화하는 @ResponseBody 어노테이션을 추가한 것으로 RESTful API를 만드는 핵심 어노테이션이다.
@RestController = @Controller + @ResponseBody
@ResonponseBody 어노테이션이 컨트롤러 메서드에서 반환되는 객체를 HTTP 응답 바디에 쓰기 위해 사용된다고 했다.
그리고 RESTful API에서는 흔히 json 형태로 데이터를 반환해야 한다.
이때 Java 객체를 json 형태로 변환하기 위해 사용되는 것이 HttpMessageConverter이다.
@Controller만 있는 경우 기본적으로 뷰를 반환하기 위해 ViewResolver가 동작하지만,
@ResponseBody를 사용하면 ViewResolver가 아닌 HttpMessageConverter가 응답을 처리하게 된다.
StringHttpMessageConverter나 MappingJackson2HttpMessageConverter 등
다양한 HttpMessageConverter가 존재하는데 클라이언트의 HTTP Accept 헤더와 String, Object 등 컨트롤러 메서드의 반환 타입을 조합해 적절한 컨버터가 선택된다.
HttpMessageConverter 인터페이스 내 일부 메서드
public interface HttpMessageConverter<T> {
boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
List<MediaType> getSupportedMediaTypes();
default List<MediaType> getSupportedMediaTypes(Class<?> clazz) {
return (canRead(clazz, null) || canWrite(clazz, null) ?
getSupportedMediaTypes() : Collections.emptyList());
}
T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException;
void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException;
}
컨트롤러에서 @ResponseBody를 이용해 HTTP 응답 바디에 객체를 json 형태로 넣고자 하면
canWrite() 메서드를 호출한다.canWrite() 조건을 만족할 경우 write() 메서드로 HTTP 응답 메시지 내 바디를 json 형태로 생성한다.정리하자면,
@ResponseBody 어노테이션을 적용하면 응답 처리 과정에서
컨트롤러 메서드에서 객체를 반환할 때 HttpMessageConverter가 동작하여
객체를 json으로 변환(직렬화)하여 HTTP 응답 본문에 json을 넣는다.
@RestController를 사용하면 클라이언트 요청 → 컨트롤러 처리 → 응답 변환 과정이 자동으로 이루어진다.
이 과정에서 DispatcherServlet, HandlerMapping, HttpMessageConverter 등이 핵심적으로 동작한다.
@RestController를 사용한 경우

그림 속 과정과 숫자가 정확히 일치하지는 않는다.
GET /users/1과 같은 특정 URI로 요청을 보낼 수 있다.Accep:application/json을 지정하면 json 형식의 응답을 요구하는 것이다.GET /users/1에 대해 UserController의 getUser() 메서드를 찾는다.이 사진은 @Controller를 사용하는 경우지만 이해하기 쉬운 사진이라 함께 첨부한다.
View Resolver 자리에 HttpMessageConverter를 대입하면 @RestController의 동작 과정이라고 볼 수 있다.

https://velog.io/@dyunge_100/Spring-Controller%EC%99%80-RestController%EC%9D%98-%EC%B0%A8%EC%9D%B4
https://mangkyu.tistory.com/49
https://cheershennah.tistory.com/179
https://yeonyeon.tistory.com/151
https://velog.io/@qkrmekem/Spring-HTTP-%EB%A9%94%EC%84%B8%EC%A7%80-%EC%BB%A8%EB%B2%84%ED%84%B0
https://jaimemin.tistory.com/1823
https://velog.io/@dyunge_100/Spring-Controller%EC%99%80-RestController%EC%9D%98-%EC%B0%A8%EC%9D%B4