@Controller 와 @RestController

텐저린티·2023년 8월 2일
0

Spring

목록 보기
2/6
post-custom-banner

@Controller, @RestController 모두 Spring 컨트롤러 지정 어노테이션.

클라이언트 HTTP요청에 대한 HTTP 응답에 포함되는 Response Body 생성 방식에 따른 차이가 있다.

@Controller

  • Spring MVC 컨트롤러
  • view 반환하기 위해 사용

📈 동작 방식

  1. 클라이언트에서 HTTP 요청
  2. DispatcherServlet에서 HandlerMapping을 이용해 요청 처리 대상 찾기
  3. 처리대상에 대한 HandlerAdapter를 통해 요청을 Controller에 위임
  4. Controller는 요청 처리 후 view name 반환
  5. DispatcherServlet은 View Resolver를 통해 view name에 대한 view를 찾아 사용자에게 반환

📝 구현

@Controller
public class ProductController {

    private final ProductService productService;

    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    @GetMapping("/products")
    public String productsPage(Model model) {
        var products = productService.getAllProducts();
        model.addAttribute("products", products);
        return "product-list";
    }
}

@Controller 어노테이션을 통해 Spring MVC를 구현하는 경우,

view를 전달하게 된다.

@ResponseBody

  • SpringMVC 컨트롤러에서 view가 아닌 데이터를 반환하고 싶은 경우 사용
  • 위에 예에서 view name을 반환하는 것이 아니라, Response Entity를 반환
  • Json, xml 형태로 데이터를 반환 가능
  • HttpMessageConverter 이용
    • View Resolver 대신 사용
    • HandlerAdapter - Controller 사이 구간에서 사용
@Controller
public class ProductController {

    private final ProductService productService;

    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    @GetMapping("/products")
    public @ReponseBody Product productsPage(Model model) {
				return ResponseEntity.ok(productService.getAllProducts());
    }
}

@RestController

  • @Controller + @ResponseBody
  • Json, xml 형태로 객체 데이터를 반환하는 목적으로 사용
  • RESTful API 개발 효자

📈 동작 방식

  1. 클라이언트 HTTP 요청
  2. DispatcherServlet이 HandlerMapping을 이용해 요청 처리 대상 탐색
  3. 요청처리 RestController에 대한 HandlerAdatper를 통해 RestController에 요청 위임
  4. RestController는 요청 처리 후 객체 반환 (Response Entity)
  5. 반환된 객체는 Json, xml 로 직렬화되어 사용자에게 반환 (HTTP 응답)

📝 구현

@RestController
public class ProductRestController {

    private final ProductService productService;

    public ProductRestController(ProductService productService) {
        this.productService = productService;
    }

    @GetMapping("/api/v1/products")
    public List<Product> productList(@RequestParam Optional<Category> category) {
        return category
                .map(productService::getProductsByCategory)
                .orElse(productService.getAllProducts());
    }
}

📌 결론

💡 가급적 RestController와 Controller 는 분리해서 작성! 💡 둘의 차이는 @ReponseBody 어노테이션 포함 유무
profile
개발하고 말테야
post-custom-banner

0개의 댓글