[Spring Boot] @RestController와 @Controller의 특징과 차이점

smlee·2022년 7월 29일
0

SpringBoot - JDBC

목록 보기
8/8

Spring에서 컨트롤러를 지정하기 위한 어노테이션은 @Controller@RestController가 있다. 언뜻보면 비슷하게 보이는 두 어노테이션의 특징과 차이점은 무엇인지 이 포스트에서 알아볼 예정이다.

💻 @Controller

전통적인 Spring MVC의 컨트롤러인 @Controller는 주로 View를 반환하기 위해 사용한다. 아래 이미지와 같은 과정을 통해 Spring MVC Container는 Client의 요청으로부터 View를 반환한다.

  1. Client는 URI 형식으로 웹 서비스에 요청을 보낸다.
  2. DispatcherServlet이 요청을 위임할 HandlerMapping을 찾는다.
  3. HandlerMapping을 통해 Controller를 위임한다.
  4. Controller는 요청을 처리한 후에 ViewName을 반환한다.
  5. DispatcherServlet은 ViewResolver를 통해 ViewName에 해당하는 View를 찾아 사용자에게 반환한다.

위처럼 Controller가 반환한 뷰의 이름으로부터 View를 렌더링하기 위해서는 ViewResolver가 사용되며, ViewResolver 설정에 맞게 View를 찾아 렌더링 한다.

하지만, @Controller로 데이터를 반환하려면 어떻게 해야할까? 컨트롤러에서는 데이터 반환을 위해 @ResponseBody 어노테이션을 사용해주어야 한다. 이를 통해 Controller가 JSON 형태로 데이터를 반환할 수 있다.


1. Client는 URI 형식으로 웹 서비스에 요청을 보낸다.
2. DispatcherServlet이 요청을 위임할 HandlerMapping을 찾는다.
3. HandlerMapping을 통해 요청을 Controller로 위임한다.
4. Controller는 요청을 처리한 후에 객체를 반환한다.
5. 반환되는 객체는 JSON으로 Serialize되어 사용자에게 반환된다.

Controller를 통해 객체를 반환할 때에는 일반적으로 ResponseEntity로 감싸서 반환을 한다. 그리고 객체를 반환하기 위해서 ViewResolver 대신에 HttpMessageConverter가 동작한다.

  • 예시
@Controller
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    @GetMapping("/users")
    public @ResponseBody ResponseEntity<User> findUser(@RequestParam("userName") String userName){
        return ResponseEntity.ok(userService.findUser(user));
    }
    
    @GetMapping("/users/detailView")
    public String detailView(Model model, @RequestParam("userName") String userName){
        User user = userService.findUser(userName);
        model.addAttribute("user", user);
        return "/users/detailView";
    }
}

👩‍💻 @RestController

RestController는 @Controller@ResponseBody가 추가된 것이다. 따라서 RestController는 JSON 형태로 객체 데이터를 반환 하는 것이 주 목적이다.

REST API를 개발할 때 주로 사용하며, 객체를 ResponseEntity로 감싸서 반환한다. 따라서 동작 과정은 @Controller@ResponseBody를 붙인것과 완벽히 동일하다.

1. Client는 URI 형식으로 웹 서비스에 요청을 보낸다.
2. DispatcherServlet이 요청을 위임할 HandlerMapping을 찾는다.
3. HandlerMapping을 통해 요청을 Controller로 위임한다.
4. Controller는 요청을 처리한 후에 객체를 반환한다.
5. 반환되는 객체는 Json으로 Serialize되어 사용자에게 반환된다.

  • 예시
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    @GetMapping("/users")
    public User findUser(@RequestParam("userName") String userName){
        return userService.findUser(user);
    }

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

✅ @Controller와 @RestController의 차이점

  • @Controller클래스를 Spring MVC 컨트롤러로 표시하는데 사용된다. 반면, @RestControllerRESTful 웹 서비스에서 사용되는 특수 컨트롤러이며 @Controller+@ResponseBody와 동일하다.

  • @RestControllerSpring 4.0에서 추가되었지만, @Controlelr는 Spring이 주석을 지원하기 시작한 이후에 존재하며 공식적으로 Spring 2.5버전에서 추가되었다.

  • @Controller@Component가 달려있다. 반면, @RestController@Controller@ResponseBody 주석이 달린 컨트롤러이다.

  • @RestController를 표시하면 모든 메소드가 뷰 대신 객체로 작성된다. 반면, @Controller는 뷰의 이름을 리턴하기도 한다.


📚 Reference

  1. [Spring] @Controller @RestController 차이
  2. @Controller와 @RestController의 차이점

0개의 댓글