Framework/Spring Framework

์š”์ฒญ์ด ์™”์„ ๋•Œ ์Šคํ”„๋ง MVC ๋‚ด๋ถ€์  ํ๋ฆ„ ๊ณผ์ • (DispatcherServlet ์ค‘์‹ฌ)

ํ”„๋กœ๊ทธ๋ž˜๋จธ ์˜ค์›” 2023. 10. 31.

Spring MVC ๊ตฌ์กฐ ํ๋ฆ„

์Šคํ”„๋ง MVC๋Š” Model-View-Controller ๋””์ž์ธ ํŒจํ„ด์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์›น ํ”„๋ ˆ์ž„์›Œํฌ๋กœ, ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ช…ํ™•ํžˆ ๋ถ„๋ฆฌํ•˜์—ฌ ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ๋†’์ธ๋‹ค.

๊ธฐ๋Šฅ๊ณผ ์—ญํ•  ๋ณ„๋กœ ๋ชจ๋“ˆ์„ ๋‚˜๋ˆ„๊ณ  ๊ฐ ๋ชจ๋“ˆ๋“ค์ด ํ˜‘๋ ฅํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธํ•œํ…Œ ์˜จ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‘๋‹ต์„ ๋ณด๋‚ด์ฃผ๊ฒŒ ๋œ๋‹ค.

๊ทธ ์ค‘  DispatcherServlet์€ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์˜ ํ•ต์‹ฌ ๊ตฌ์„ฑ ์š”์†Œ๋กœ, ์Šคํ”„๋ง MVC์˜ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ(Front Controller) ์—ญํ• ์„ ํ•œ๋‹ค. ๋ชจ๋“  HTTP ์š”์ฒญ์€ ๋จผ์ € DispatcherServlet์„ ํ†ตํ•ด ์ฒ˜๋ฆฌ๋˜๋ฉฐ, ์ด๊ณณ์—์„œ ์š”์ฒญ์„ ์ ์ ˆํ•œ ์ปจํŠธ๋กค๋Ÿฌ, ์„œ๋น„์Šค, ๋ทฐ๋กœ ๋ผ์šฐํŒ…ํ•œ๋‹ค. DispatcherServlet์€ ์Šคํ”„๋ง ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ค‘์•™ ์ œ์–ด ์ง€์ ์œผ๋กœ, ์š”์ฒญ์˜ ์ฒ˜๋ฆฌ ํ๋ฆ„์„ ๊ด€๋ฆฌํ•œ๋‹ค.

 

์š”์•ฝ

 

 

 

์ƒ์„ธ

 

 

์Šคํ”„๋ง MVC ๊ฐ ๋ชจ๋“ˆ๋ณ„ ์š”์ฒญ ์ฒ˜๋ฆฌ ํ๋ฆ„

  1. ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ (Client Request)
    • ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €, ๋ชจ๋ฐ”์ผ ์•ฑ ๋“ฑ)๊ฐ€ ํŠน์ • URL๋กœ HTTP ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.
  2. ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ (DispatcherServlet)
    • ์š”์ฒญ์€ ๋จผ์ € DispatcherServlet์— ๋„๋‹ฌํ•œ๋‹ค. ์ด๋Š” ์Šคํ”„๋ง MVC์˜ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ์—ญํ• ์„ ํ•˜๋ฉฐ, ๋ชจ๋“  ์š”์ฒญ์„ ์ค‘์•™์—์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค.
    • DispatcherServlet์€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ web.xml ํŒŒ์ผ ๋˜๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ์˜ ์ž๋™ ์„ค์ •์— ์˜ํ•ด ์„ค์ •๋œ๋‹ค.
  3. ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘ (Handler Mapping)
    • DispatcherServlet์€ ์š”์ฒญ URL์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ ์ ˆํ•œ ์ปจํŠธ๋กค๋Ÿฌ(Handler)๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘ ์ „๋žต์„ ์‚ฌ์šฉํ•œ๋‹ค.
    • ์Šคํ”„๋ง MVC๋Š” ๋‹ค์–‘ํ•œ ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘์„ ์ œ๊ณตํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, RequestMappingHandlerMapping์€ @RequestMapping ์• ๋…ธํ…Œ์ด์…˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์„œ๋“œ๋ฅผ ๋งคํ•‘ํ•œ๋‹ค.
  4. ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ (Handler Adapter)
    • ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘์— ์˜ํ•ด ์„ ํƒ๋œ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด DispatcherServlet์€ ์ ์ ˆํ•œ ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋ฅผ ์„ ํƒํ•œ๋‹ค.
    • ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์‹ค์ œ ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. Spring MVC๋Š” ์—ฌ๋Ÿฌ ์œ ํ˜•์˜ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐ ์ปจํŠธ๋กค๋Ÿฌ ํƒ€์ž…์— ๋งž๋Š” ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
    • ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋Š” ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  5. ์ปจํŠธ๋กค๋Ÿฌ (Controller)
    • ์ปจํŠธ๋กค๋Ÿฌ๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ , ํ•„์š”ํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ๋ชจ๋ธ ๋ฐ์ดํ„ฐ๋ฅผ ์ค€๋น„ํ•œ๋‹ค.
    • ์ปจํŠธ๋กค๋Ÿฌ๋Š” @Controller ๋˜๋Š” @RestController ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜๋œ๋‹ค.
    @Controller
    @RequestMapping("/users")
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        @GetMapping("/{id}")
        public String getUser(@PathVariable Long id, Model model) {
            User user = userService.getUserById(id);
            model.addAttribute("user", user);
            return "userDetail";
        }
    }
  6. ๋ชจ๋ธ (Model)
    • ๋ชจ๋ธ์€ ์ปจํŠธ๋กค๋Ÿฌ์— ์˜ํ•ด ์ค€๋น„๋œ ๋ฐ์ดํ„ฐ๋กœ, ๋ทฐ์— ์ „๋‹ฌ๋  ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•œ๋‹ค.
    • Model ๋˜๋Š” ModelMap ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ทฐ์— ์ „๋‹ฌํ•œ๋‹ค.
  7. ๋ทฐ ๋ฆฌ์กธ๋ฒ„ (View Resolver)
    • ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ๋…ผ๋ฆฌ์  ๋ทฐ ์ด๋ฆ„์„ ์‹ค์ œ ๋ทฐ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด DispatcherServlet์€ ๋ทฐ ๋ฆฌ์กธ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
    • ์Šคํ”„๋ง MVC๋Š” ์—ฌ๋Ÿฌ ๋ทฐ ๋ฆฌ์กธ๋ฒ„๋ฅผ ์ง€์›ํ•˜๋ฉฐ, ์ฃผ๋กœ InternalResourceViewResolver (JSP), ThymeleafViewResolver (Thymeleaf), FreeMarkerViewResolver (FreeMarker) ๋“ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค.
    • DTO(Data Transfer Object)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ObjectMapper (์˜ค๋ธŒ์ ํŠธ ๋งคํผ)๋ฅผ ํ†ตํ•ด JSON ์‘๋‹ต์œผ๋กœ ๋ณด๋‚ด๋Š” ๊ฒฝ์šฐ, ๋ทฐ ๋ฆฌ์กธ๋ฒ„ ๊ณผ์ •์€ ์ƒ๋žต๋œ๋‹ค.
    <!-- ์Šคํ”„๋ง ์„ค์ • ํŒŒ์ผ -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
  8. ๋ทฐ (View)
    • ๋ทฐ๋Š” ๋ชจ๋ธ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด๋‚ผ HTML, JSON, XML ๋“ฑ์˜ ์‘๋‹ต์„ ์ƒ์„ฑํ•œ๋‹ค.
    • JSP, Thymeleaf, FreeMarker ๋“ฑ์˜ ํ…œํ”Œ๋ฆฟ ์—”์ง„์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ทฐ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.
    <html>
    <body>
        <h1>User Detail</h1>
        <p>ID: ${user.id}</p>
        <p>Name: ${user.name}</p>
        <p>Email: ${user.email}</p>
    </body>
    </html>
  9. ์‘๋‹ต ๋ฐ˜ํ™˜ (Response Return)
    • ์ตœ์ข…์ ์œผ๋กœ ๋ทฐ์—์„œ ์ƒ์„ฑ๋œ ์‘๋‹ต์ด DispatcherServlet์„ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฐ˜ํ™˜๋œ๋‹ค.

 

์š”์•ฝ

  • ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ: ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.
  • ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ: ์š”์ฒญ์„ ๋ฐ›์•„ ์ ์ ˆํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฐพ๊ณ  ์‹คํ–‰ํ•œ๋‹ค.
  • ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘: ์š”์ฒญ URL์— ๋งคํ•‘๋œ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ฐพ๋Š”๋‹ค.
  • ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ: ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ •์˜ํ•œ๋‹ค.
  • ์ปจํŠธ๋กค๋Ÿฌ: ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋ชจ๋ธ ๋ฐ์ดํ„ฐ๋ฅผ ์ค€๋น„ํ•œ๋‹ค.
  • ๋ชจ๋ธ: ๋ทฐ์— ์ „๋‹ฌ๋  ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•œ๋‹ค.
  • ๋ทฐ ๋ฆฌ์กธ๋ฒ„: ๋…ผ๋ฆฌ์  ๋ทฐ ์ด๋ฆ„์„ ์‹ค์ œ ๋ทฐ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
  • ๋ทฐ: ๋ชจ๋ธ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์‘๋‹ต์„ ์ƒ์„ฑํ•œ๋‹ค.
  • ์‘๋‹ต ๋ฐ˜ํ™˜: ์ƒ์„ฑ๋œ ์‘๋‹ต์ด ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋Œ“๊ธ€