[Spring] @Controller와 @RestController의 차이점

2024. 12. 29. 22:27·Study/Spring

Spring에서 컨트롤러를 구현할 때 `@Controller`와 `@RestController` 두 가지 어노테이션을 사용할 수 있다.

이 두 가지 방식의 차이점과 사용법에 대해 자세히 알아보자!

 

📌 @Controller

`@Controller`는 전통적인 Spring MVC 컨트롤러로, 주로 View를 반환하기 위해 사용된다.

1. View 반환하기

@Controller
public class ViewController {

    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("message", "안녕하세요");
        return "hello"; // hello.jsp나 hello.html 같은 뷰 파일을 찾는다.
    }
}
  1. 클라이언트가 `/hello` URL로 요청을 보낸다.
  2. DispatcherServlet이 Handler Mapping을 통해 요청 URL에 맞는 컨트롤러와 메서드를 찾는다.
  3. Handler Adapter를 통해 컨트롤러를 실행한다.
  4. 컨트롤러가 model에 데이터를 담고 view 이름을 반환한다.
  5. ViewResolver가 view이름("hello")을 실제 물리적 view 파일 경로(/templates/hello.html)로 변환한다.
  6. view가 model 데이터를 사용해 화면을 생성해 클라이언트에게 제공한다.

Controller로 View 반환하는 과정

 

2. Data 반환하기

웹 애플리케이션이 발전하면서 view 대신 data를 직접 반환해야 하는 경우가 많아졌는데,

`@Controller`에서 데이터를 반환하려면 `@ResponseBody` 어노테이션을 활용해야 한다.

@Controller
public class DataController {
    
    // 데이터 반환 - ResponseEntity 사용
    @GetMapping("/message")
    @ResponseBody
    public ResponseEntity<Message> getMessage() {
        Message message = new Message("안녕하세요");
        return ResponseEntity.ok(message);
    }

    // HTTP 상태 코드를 포함한 응답
    @PostMapping("/messages")
    @ResponseBody
    public ResponseEntity<Message> createMessage(@RequestBody MessageRequest request) {
        Message savedMessage = messageService.save(request);
        return ResponseEntity.status(HttpStatus.CREATED)
                           .body(savedMessage);
    }
}

`@ResponseBody`를 사용하면 ViewResolver 대신 HttpMessageConverter가 동작해 객체를 JSON 형식으로 변환한다.

`ResponseEntity`를 사용하면 HTTP 상태 코드, 헤더, 본문을 모두 제어할 수 있어 더 세밀한 응답 제어가 가능하다.

Controller로 Data 반환하는 과정

 


 

📌 @RestController의 등장

컨트롤러에 @ResponseBody를 모든 메서드에 적용해야 하는 번거로움을 해결하기 위해 @RestController가 등장하게 되었다.

`@RestController`는 `@Controller`와 `@ResponseBody`가 결합된 어노테이션으로
REST API 개발에 주로 사용된다.

 

아래 소스코드를 살펴보면, @Controller는 @Component 주석이 있고

@RestController는 @Controller와 @ResponseBody가 포함되어 있는 것을 확인할 수 있다.

`@RestController`를 사용하면 클래스 내의 모든 메서드에 자동으로 @ResponseBody가 적용되는 것이다.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller


@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController

  1. 클라이언트의 HTTP 요청이 Dispatcher Servlet으로 전달된다.
  2. Dispatcher Servlet은 Handler Mapping을 통해 요청을 처리할 적절한 Controller를 찾는다.
  3. Dispatcher Servlet은 Handler Adapter를 통해 해당 Controller를 호출할 준비를 한다.
  4. Handler Adapter는 실제 RestController를 호출하여 비즈니스 로직을 처리한다.
  5. RestController는 비즈니스 로직 처리를 위해 Service 계층을 호출하고, 필요한 경우 Repository를 통해 Database에 접근한다.
  6. Service 계층에서 처리된 결과는 ResponseEntity 객체로 변환된다.
  7. ResponseEntity는 Handler Adapter를 통해 Dispatcher Servlet으로 전달된다.
  8. 최종적으로 Dispatcher Servlet은 응답을 클라이언트에게 반환한다.

 

`@RestController`를 사용하면 모든 메서드에 `@ResponseBody`가 적용되어 데이터를 반환할 때마다 어노테이션을 추가하지 않아도 된다. 주로 REST API를 개발할 때 사용되며, 다음 예시를 통해 ResponseEntity의 필요성을 살펴보도록 하자.

@RestController  // @Controller + @ResponseBody
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    // 단순 객체 반환
    @GetMapping(value = "/users")
    public User findUser(@RequestParam String userName){
        return userService.findUser(userName);
    }

    // ResponseEntity 사용
    @GetMapping(value = "/users")
    public ResponseEntity<User> findUserWithResponseEntity(@RequestParam String userName){
        return ResponseEntity.ok(userService.findUser(userName));
    }
}

첫 번째 메서드처럼 객체를 직접 반환하면 HTTP 상태 코드를 세밀하게 제어할 수 없다.

예를 들어 사용자를 찾지 못했을 때 404 Not Found를 반환하거나, 서버 오류 시 500 Internal Server

Error를 반환하는 등의 처리가 불가능하다.

 

반면 ResponseEntity를 사용하면 다양한 상황에 맞는 적절한 HTTP 상태 코드를 반환할 수 있다

  • 리소스를 찾을 수 없을 때: 404 Not Found
  • 잘못된 요청일 때: 400 Bad Request
  • 서버 오류 발생 시: 500 Internal Server Error
  • 정상 처리 시: 200 OK

따라서 REST API를 구현할 때는 ResponseEntity를 사용하여 더 명확한 응답을 제공하는 것이 좋다.

 

📌 @Controller와 @RestController 비교

특성 @Controller @RestController
View 반환 여부 O X
JSON 데이터 반환 @ResponseBody 필요 기본 동작
주요 사용 사례 템플릿 렌더링 REST API 개발

 

정리해보면

`@Controller`는 View 템플릿을 사용하는 전통적인 웹 애플리케이션에 유용하다.

`@RestController`는 RESTful API 개발을 위한 간결하고 효율적인 방법을 제공한다.

REST API 구현 시 `ResponseEntity`를 사용하면 HTTP 상태 코드와 응답 구조를 세밀하게 제어할 수 있다.

 

사용하려는 애플리케이션의 요구 사항에 따라 적절한 어노테이션을 선택해서 개발하면 된다!!!!

 


🗂️ References

Spring 공식 문서

[Spring] @Controller와 @RestController 차이

[Spring] @Controller와 @RestController의 차이점 알아보기

 

'Study > Spring' 카테고리의 다른 글

[Spring] Bean Validation 활용한 효율적인 검증 구현하기  (0) 2025.01.14
[Spring] BindingResult 활용한 Validation 검증 동작 방식  (0) 2025.01.07
'Study/Spring' 카테고리의 다른 글
  • [Spring] Bean Validation 활용한 효율적인 검증 구현하기
  • [Spring] BindingResult 활용한 Validation 검증 동작 방식
ssuzyn
ssuzyn
  • ssuzyn
    멋쟁이 개발자
    ssuzyn
  • 링크

    • github
    • velog
  • 전체
    오늘
    어제
    • 분류 전체보기 (71)
      • 프로젝트 (9)
        • 짠모아 (6)
        • 피노키오 (0)
      • 코딩 테스트 (39)
        • Baekjoon (27)
        • SWEA (11)
        • Programmers (1)
      • Study (3)
        • Spring (3)
        • Algorithm (0)
      • SSAFY (18)
      • 이모저모 (2)
  • 인기 글

  • 블로그 메뉴

    • 홈
    • 방명록
  • hELLO· Designed By정상우.v4.10.0
ssuzyn
[Spring] @Controller와 @RestController의 차이점
상단으로

티스토리툴바