Featured image of post Spring MVC

Spring MVC

Controller VS RestController

๐Ÿ“Œ๊ฐœ์š”

Spring MVC๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์›น ํ”„๋ ˆ์ž„์›Œํฌ๋‹ค. ์ด๋•Œ ํ•ต์‹ฌ์ ์ธ ์—ญํ• ์„ ํ•˜๋Š” ๊ฒƒ์ด @Controller, @RestController์ด๋‹ค.

๋‘ ์–ด๋…ธํ…Œ์ด์…˜์€ ๋น„์Šทํ•ด๋ณด์ด์ง€๋งŒ ์‘๋‹ต ๋ฐฉ์‹์—์„œ ์ค‘์š”ํ•œ ์ฐจ์ด๋ฅผ ๊ฐ€์ง„๋‹ค.

๐Ÿ“Œ๋‚ด์šฉ

์š”์ฒญ ์ฒ˜๋ฆฌ ํ๋ฆ„

    sequenceDiagram
    participant Client
    participant DispatcherServlet
    participant HandlerMapping
    participant HandlerAdapter
    participant Controller
    participant ViewResolver
    participant HttpMessageConverter

    Client->>DispatcherServlet: HTTP ์š”์ฒญ
    DispatcherServlet->>HandlerMapping: ํ•ธ๋“ค๋Ÿฌ ํƒ์ƒ‰
    HandlerMapping-->>DispatcherServlet: ํ•ธ๋“ค๋Ÿฌ ๋ฐ˜ํ™˜
    DispatcherServlet->>HandlerAdapter: ํ•ธ๋“ค๋Ÿฌ ์‹คํ–‰ ์œ„์ž„
    HandlerAdapter->>Controller: ๋ฉ”์„œ๋“œ ์‹คํ–‰

    alt @Controller
        Controller-->>HandlerAdapter: View ์ด๋ฆ„ ๋ฐ˜ํ™˜
        HandlerAdapter->>ViewResolver: View ์ด๋ฆ„์œผ๋กœ View ๊ฐ์ฒด ์ƒ์„ฑ
        ViewResolver-->>DispatcherServlet: View ๊ฐ์ฒด (HTML ํฌํ•จ)
    else @RestController
        Controller-->>HandlerAdapter: ๊ฐ์ฒด ๋ฐ˜ํ™˜
        HandlerAdapter->>HttpMessageConverter: ๊ฐ์ฒด๋ฅผ JSON์œผ๋กœ ์ง๋ ฌํ™”
        HttpMessageConverter-->>DispatcherServlet: ์ง๋ ฌํ™”๋œ JSON
    end

    DispatcherServlet-->>Client: ์‘๋‹ต ์ „์†ก
  
  1. Client๊ฐ€ HTTP ์š”์ฒญ์„ ํ•˜๊ฒŒ ๋˜๋ฉด DispatcherServlet์ด ๊ฐ€๋กœ์ฑ”
    • ๋ชจ๋“  HTTP ์š”์ฒญ์€ DispatcherServlet์ด ๊ฐ€๋กœ์ฑ„๋ฉฐ ์‹œ์ž‘๋œ๋‹ค.
  2. DispatcherServlet์€ HandlerMapping์„ ํ†ตํ•ด ํ•ด๋‹น ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  Handler๋ฅผ ์ฐพ์€ ๋‹ค์Œ HandlerAdapter์—๊ฒŒ ํ•ด๋‹น ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ์œ„์ž„ํ•œ๋‹ค.
    • ์‹คํ–‰์„ ์œ„์ž„ํ•œ๋‹ค.
  3. HandlerAdapter๋Š” Controller์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
    • ์–ด๋–ค Handler๊ฐ€ ๋๋“  HandlerAdapter๊ฐ€ ์‹ค์ œ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
  4. @Controller, @RestController ์ผ€์ด์Šค์˜ Resolver ํ˜ธ์ถœ
    1. @Controller ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ๋“ฑ๋ก๋œ ๋ฉ”์„œ๋“œ์˜ ๊ฒฝ์šฐ Controller๊ฐ€ ๋ฐ˜ํ™˜ํ•œ View ์ด๋ฆ„๊ณผ Model ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ DispatcherServlet์ด ViewResolver๋ฅผ ํ†ตํ•ด View ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ๋’ค ์ด๋ฅผ ๋ Œ๋”๋งํ•˜์—ฌ ์‘๋‹ต์„ ์ƒ์„ฑํ•œ๋‹ค.
      • ViewResolver๋Š” ๋‹จ์ˆœํžˆ View๋ฅผ ์ฐพ์•„์ฃผ๋Š” ์—ญํ• 
      • ์‹ค์ œ ๋ Œ๋”๋ง์€ View ๊ฐ์ฒด๊ฐ€ ์ˆ˜ํ–‰ํ•œ๋‹ค.
    2. @RestController ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ๋“ฑ๋ก๋œ ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ๊ฐ์ฒด๋Š” DispatcherServlet โ†’ HandlerAdapter โ†’ HttpMessageConverter๋ฅผ ํ†ตํ•ด JSON์„ ์ƒ์„ฑํ•œ ๋’ค DispatcherServlet์—๊ฒŒ ์ „๋‹ฌํ•œ๋‹ค.
      • ์ง๋ ฌํ™” ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•œ๋‹ค.
  5. @Controller, @RestController ์ผ€์ด์Šค์˜ ์‘๋‹ต ๋ฐ˜ํ™˜
    1. @Controller์˜ ๊ฒฝ์šฐ ViewResolver๋Š” View ์ด๋ฆ„์— ํ•ด๋‹นํ•˜๋Š” View ๊ฐ์ฒด๋ฅผ ์ฐพ๋Š” ์—ญํ• ๋งŒ ํ•˜๊ณ  ํ•ด๋‹น View ๊ฐ์ฒด๊ฐ€ DispatcherServlet์˜ ํ˜ธ์ถœ์— ์˜ํ•ด ์‹ค์ œ HTML์„ ๋ Œ๋”๋งํ•ด ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌํ•œ๋‹ค.
      • ViewResolver โ†’ View ๊ฐ์ฒด ํƒ์ƒ‰
      • View โ†’ HTML ๋ Œ๋”๋ง
    2. @RestController์˜ ๊ฒฝ์šฐ HttpMessageConverter๋Š” ๊ฐ์ฒด๋ฅผ JSON์œผ๋กœ ์ง๋ ฌํ™”๋งŒ ํ•˜๊ณ  ์ง๋ ฌํ™”๋œ ๊ฒฐ๊ณผ๋Š” DispatcherServelet์„ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฐ˜ํ™˜๋œ๋‹ค.
      • DispatcherServlet์ด ์‘๋‹ต์˜ ์‹œ์ž‘๊ณผ ๋์„ ๋‹ด๋‹นํ•˜๋ฉฐ HttpMessageConverter๋Š” ์‘๋‹ต ๋ณธ๋ฌธ ์ƒ์„ฑ์„ ๋•๋Š”๋‹ค.

@Controller

  • ์ „ํ†ต์ ์ธ MVC ๊ตฌ์กฐ์—์„œ ์‚ฌ์šฉ
  • Model์— ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๊ณ  View ์ด๋ฆ„์„ ๋ฐ˜ํ™˜
  • View Resolver๊ฐ€ View ํ…œํ”Œ๋ฆฟ์„ ๋ Œ๋”๋งํ•˜์—ฌ ์‘๋‹ต
1
2
3
4
5
6
7
8
9
@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("name", "Nine");
        return "hello"; // templates/hello.html
    }
}
  • JSON ์‘๋‹ต์„ ์œ„ํ•ด @ResponseBody์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    @Controller
    public class ApiController {
    
        @ResponseBody
        @GetMapping("/api/hello")
        public String apiHello() {
            return "Hello from Controller!";
        }
    }
    

@RestController

  • RESTful ์›น ์„œ๋น„์Šค์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ
  • @Controller + @ResponseBody์˜ ์กฐํ•ฉ
  • ๋ฆฌํ„ด๊ฐ’์„ ๊ทธ๋Œ€๋กœ JSON ๋“ฑ์œผ๋กœ ์ง๋ ฌํ™”ํ•˜์—ฌ Response Body๋กœ ์ „๋‹ฌ
1
2
3
4
5
6
7
8
@RestController
public class HelloRestController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello, Nine!";
    }
}

์ฐจ์ด์  ๋น„๊ต

๊ตฌ๋ถ„ ํ•ญ๋ชฉ@Controller@RestController
๋ฆฌํ„ด ํƒ€์ž…View ์ด๋ฆ„ ๋˜๋Š” ModelAndView ๊ฐ์ฒด / ResponseEntity ์ง์ ‘ ์ง๋ ฌํ™”ํ•œ ๋ฐ์ดํ„ฐ๊ฐ์ฒด ๋˜๋Š” ๋ฌธ์ž์—ด (์ž๋™ JSON ์ง๋ ฌํ™”๋จ)
์‚ฌ์šฉ ๋ชฉ์ ํ…œํ”Œ๋ฆฟ ๋ Œ๋”๋ง ๊ธฐ๋ฐ˜ ์›น ์•ฑ (HTML) / ํ•„์š”์‹œ JSON ์‘๋‹ต๋„ ๊ฐ€๋ŠฅAPI ์‘๋‹ต์„ ์œ„ํ•œ JSON/๋ฐ์ดํ„ฐ ์ „์†ก์šฉ
์‘๋‹ต ์ฒ˜๋ฆฌViewResolver๋ฅผ ํ†ตํ•ด HTML ๋ Œ๋”๋งHttpMessageConverter๋ฅผ ํ†ตํ•ด JSON ์ง๋ ฌํ™”
์กฐํ•ฉ ์–ด๋…ธํ…Œ์ด์…˜@Controller, @ResponseBody ํ•„์š”@RestController ๋‹จ๋… ์‚ฌ์šฉ ๊ฐ€๋Šฅ

๐ŸŽฏ๊ฒฐ๋ก 

  • @Controller๋Š” View ๊ธฐ๋ฐ˜ ์‘๋‹ต์„ ๊ธฐ๋ณธ์œผ๋กœ ํ•˜์ง€๋งŒ @ResponseBody๋‚˜ ResponseEntity๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด JSON ๋ฐ์ดํ„ฐ๋„ ์‘๋‹ตํ•  ์ˆ˜ ์žˆ๋‹ค.
  • @RestController๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ์ดํ„ฐ(JSON ๋“ฑ) ์‘๋‹ต์„ ๊ธฐ๋ณธ์œผ๋กœ ํ•˜๋ฉฐ, API ์„œ๋ฒ„ ๊ตฌํ˜„์— ์ ํ•ฉํ•˜๋‹ค.

Spring MVC์—์„œ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ๋ฆ„์„ ์ดํ•ดํ•˜๋ฉด, ์ƒํ™ฉ์— ๋งž๋Š” ์–ด๋…ธํ…Œ์ด์…˜ ์„ ํƒ์ด ์‰ฌ์›Œ์ง„๋‹ค. View ๊ธฐ๋ฐ˜ ์›น ํŽ˜์ด์ง€์™€ RESTful API๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ด๋‹ค.

โš™๏ธEndNote

์‚ฌ์ „ ์ง€์‹

  • MVC ๋””์ž์ธ ํŒจํ„ด
  • Servlet๊ณผ DispatcherServlet์˜ ์—ญํ• 
  • View Resolver, HttpMessageConverter ์ž‘๋™ ์›๋ฆฌ

๋” ์•Œ์•„๋ณด๊ธฐ