๐Ÿ“‹ Spring MVC - 3. ์„œ๋ธ”๋ฆฟ, JSP, MVC ํŒจํ„ด


์Šคํ”„๋ง MVC ์ „์ฒด ๊ตฌ์กฐ

์ง€๊ธˆ๊ป ๋งŒ๋“ค์—ˆ๋˜ ํ”„๋ ˆ์ž„ ์›Œํฌ <-> ์Šคํ”„๋ง MVC

  • FrontController - DispatcherServlet
  • HandlerMappingMap - HandlerMapping
  • MyHandlerAdapter - HandlerAdapter
  • ModelView - ModelAndView
  • ViewResolver - ViewResolver
  • MyView - View

DispatcherServlet

DispacherServlet ๋„ ๋ถ€๋ชจ ํด๋ž˜์Šค์—์„œ HttpServlet ์„ ์ƒ์† ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•˜๊ณ , ์„œ๋ธ”๋ฆฟ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

์Šคํ”„๋ง ๋ถ€ํŠธ๋Š” DispatcherServlet๋ฅผ ์ž๋™์œผ๋กœ ๋“ฑ๋กํ•˜๋ฉด์„œ ๋ชจ๋“  ๊ฒฝ๋กœ์— ๋Œ€ํ•ด์„œ ๋งคํ•‘ํ•œ๋‹ค.

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

DispatcherServlet์ด ํ˜ธ์ถœ๋˜๋ฉด service() ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
์ตœ์ข…์ ์œผ๋กœ๋Š” DispatcherServlet.doDispatch()` ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.

doDispatch()

DispatcherServlet์˜ doDispatch()์˜ ์ฃผ์š” ๋ถ€๋ถ„๋“ค์„ ์‚ดํŽด๋ณด์ž!

  • ModelAndView
  • getHandler() : ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
    • ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์—†์œผ๋ฉด 404๋กœ ์…‹ํŒ…์„ ํ•œ๋‹ค.
  • getHandlerAdapter() : ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

  • ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋กœ ํ•ธ๋“ค๋Ÿฌ ํ˜ธ์ถœํ•˜๊ณ  ModelAndView ๋ฐ˜ํ™˜

  • view ๋ Œ๋”๋ง ํ˜ธ์ถœ

  • ViewResolver๋ฅผ ํ†ตํ•ด์„œ view๋ฅผ ์ฐพ์•„ ๋ฐ˜ํ™˜

  • View ๋ Œ๋”๋ง

์Šคํ”„๋ง MVC ๊ตฌ์กฐ

  1. ํ•ธ๋“ค๋Ÿฌ ์กฐํšŒ : ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘์„ ํ†ตํ•ด ์š”์ฒญ URL์— ๋งคํ•‘๋œ ํ•ธ๋“ค๋Ÿฌ ์กฐํšŒ
  2. ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ ์กฐํšŒ : ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ ์กฐํšŒ
  3. ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ ์‹คํ–‰ : ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ ์‹คํ–‰
  4. ํ•ธ๋“ค๋Ÿฌ ์‹คํ–‰ : ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๊ฐ€ ์‹ค์ œ ํ•ธ๋“ค๋Ÿฌ ์‹คํ–‰
  5. ModelAndView ๋ฐ˜ํ™˜ : ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋Š” ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ •๋ณด๋ฅผ ModelAndView๋กœ ๋ณ€ํ™˜ํ•ด์„œ ๋ฐ˜ํ™˜
  6. viewResolver ํ˜ธ์ถœ : JSP์˜ ๊ฒฝ์šฐ InternalResourceViewResolver ๊ฐ€ ์ž๋™์œผ๋กœ ๋“ฑ๋ก๋˜๊ณ  ์‚ฌ์šฉ๋จ
  7. view ๋ฐ˜ํ™˜ : ๋ทฐ ๋ฆฌ์กธ๋ฒ„๋Š” ๋ทฐ์˜ ๋…ผ๋ฆฌ ์ด๋ฆ„์„ ๋ฌผ๋ฆฌ ์ด๋ฆ„์œผ๋กœ ๋ฐ”๊พธ๊ณ  ๋ Œ๋”๋ง ์—ญํ• ์„ ๋‹ด๋‹นํ•˜๋Š” ๋ทฐ ๊ฐ์ฒด ๋ฐ˜ํ™˜
    • JSP์˜ ๊ฒฝ์šฐ InternalResourceViewResolver(JstlView) ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๋‚ด๋ถ€์— forward() ๋กœ์ง์ด ์žˆ๋‹ค.
  8. ๋ทฐ ๋ Œ๋”๋ง : ๋ทฐ๋ฅผ ํ†ตํ•ด์„œ ๋ทฐ๋ฅผ ๋ Œ๋”๋ง ํ•œ๋‹ค.

๊ฐ€์žฅ ํฐ ์žฅ์ ์€ DispatcherServlet ์ฝ”๋“œ์˜ ๋ณ€๊ฒฝ ์—†์ด ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.
๋Œ€๋ถ€๋ถ„ ํ™•์žฅ ๊ฐ€๋Šฅํ•˜๋„๋ก ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ œ๊ณตํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ์‚ฌ์‹ค ์šฐ๋ฆฌ๊ฐ€ ํ™•์žฅํ•  ์ปจํŠธ๋กค๋Ÿฌ๋Š” ๊ฑฐ์˜ ์—†๋‹ค.


ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘๊ณผ ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ

๊ณผ๊ฑฐ Controller ์ธํ„ฐํŽ˜์ด์Šค

public interface Controller {
    ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
  • @Component : โ€œโ€œ/springmvc/old-controller: ๋ผ๋Š” ์ด๋ฆ„์˜ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก
  • ๋นˆ์˜ ์ด๋ฆ„์œผ๋กœURL์„ ๋งคํ•‘

์œ„ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๋ฐฉ์‹

  • HandlerMapping(ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘)
    • ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘์—์„œ ์ด ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ ex) ์Šคํ”„๋ง ๋นˆ์˜ ์ด๋ฆ„์œผ๋กœ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘ ํ•„์š”
  • HandlerAdapter(ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ)
    • ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘์„ ํ†ตํ•ด์„œ ์ฐพ์€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๊ฐ€ ํ•„์š” ex) Controller ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋ฅผ ์ฐพ๊ณ  ์‹คํ–‰ํ•ด์•ผ ํ•จ
  • ์Šคํ”„๋ง์€ ์ด๋ฏธ ํ•„์š”ํ•œ ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘๊ณผ ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋ฅผ ๋Œ€๋ถ€๋ถ„ ๊ตฌํ˜„ํ•ด๋‘์—ˆ๋‹ค.

์Šคํ”„๋ง ๋ถ€ํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘๊ณผ ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ

  • HandlerMapping
    • RequestMappingHandlerMapping : ์• ๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์˜ ์ปจํŠธ๋กค๋Ÿฌ์ธ @RequestMapping์—์„œ ์‚ฌ์šฉ - ๊ฐ€์žฅ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์Œ
    • BeanNameUrlHandlerMapping : ์Šคํ”„๋ง ๋นˆ์˜ ์ด๋ฆ„์œผ๋กœ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฐพ๋Š”๋‹ค. (์œ„ ์˜ˆ์ œ์˜ @Component)
  • HandlerAdapter
    • RequestMappingHandlerAdapter : ์• ๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์˜ ์ปจํŠธ๋กค๋Ÿฌ์ธ @RequestMapping์—์„œ ์‚ฌ์šฉ - ๊ฐ€์žฅ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์Œ
    • HttpRequestHandlerAdapter : HttpRequestHandler ์ฒ˜๋ฆฌ
    • SimpleControllerHandlerAdapter : Controller ์ธํ„ฐํŽ˜์ด์Šค(์• ๋…ธํ…Œ์ด์…˜X, ๊ณผ๊ฑฐ์— ์‚ฌ์šฉ) ์ฒ˜๋ฆฌ
1. ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘์œผ๋กœ ํ•ธ๋“ค๋Ÿฌ ์กฐํšŒ

HandlerMapping ์„ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰ํ•ด์„œ, ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฐพ๋Š”๋‹ค.

๋นˆ์ด๋ฆ„์œผ๋กœ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฐพ์•„์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋นˆ์ด๋ฆ„์œผ๋กœํ•ธ๋“ค๋Ÿฌ๋ฅผ์ฐพ์•„์ฃผ๋Š” BeanNameUrlHandlerMapping๊ฐ€ ์‹คํ–‰์— ์„ฑ๊ณตํ•˜๊ณ  ํ•ธ๋“ค๋Ÿฌ์ธ OldController ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

2. ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ ์กฐํšŒ

HandlerAdapter ์˜ supports() ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ํ˜ธ์ถœํ•œ๋‹ค. SimpleControllerHandlerAdapter ๊ฐ€ Controller ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง€์›ํ•˜๋ฏ€๋กœ ๋Œ€์ƒ์ด ๋œ๋‹ค.

3. ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ ์‹คํ–‰

DispatcherServlet์ด ์กฐํšŒํ•œ SimpleControllerHandlerAdapter ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด์„œ ํ•ธ๋“ค๋Ÿฌ ์ •๋ณด๋„ ํ•จ๊ป˜ ๋„˜๊ฒจ์ค€๋‹ค.

SimpleControllerHandlerAdapter ๋Š” ํ•ธ๋“ค๋Ÿฌ์ธ OldController ๋ฅผ ๋‚ด๋ถ€์—์„œ ์‹คํ–‰ํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

HttpRequestHandler

 public interface HttpRequestHandler {
         void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}

  • ์„œ๋ธ”๋ฆฟ๊ณผ ๊ฐ€์žฅ ์œ ์‚ฌํ•œ ํ˜•ํƒœ์˜ ํ•ธ๋“ค๋Ÿฌ
1. ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘์œผ๋กœ ํ•ธ๋“ค๋Ÿฌ ์กฐํšŒ

HandlerMapping ์„ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰ํ•ด์„œ, ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฐพ๋Š”๋‹ค.

๋นˆ์ด๋ฆ„์œผ๋กœ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฐพ์•„์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋นˆ์ด๋ฆ„์œผ๋กœ ํ•ธ๋“ค๋Ÿฌ๋ฅผ์ฐพ์•„์ฃผ๋Š” BeanNameUrlHandlerMapping ๊ฐ€ ์‹คํ–‰์— ์„ฑ๊ณตํ•˜๊ณ  ํ•ธ๋“ค๋Ÿฌ์ธ MyHttpRequestHandler ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

2. ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ ์กฐํšŒ

HandlerAdapter ์˜ supports() ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ํ˜ธ์ถœํ•œ๋‹ค. HttpRequestHandlerAdapter ๊ฐ€ HttpRequestHandler ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง€์›ํ•˜๋ฏ€๋กœ ๋Œ€์ƒ์ด ๋œ๋‹ค.

3. ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ ์‹คํ–‰

DispatcherServlet์ด ์กฐํšŒํ•œ HttpRequestHandlerAdapter ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด์„œ ํ•ธ๋“ค๋Ÿฌ ์ •๋ณด๋„ ํ•จ๊ป˜ ๋„˜๊ฒจ์ค€๋‹ค.

HttpRequestHandlerAdapter ๋Š” ํ•ธ๋“ค๋Ÿฌ์ธ MyHttpRequestHandler ๋ฅผ ๋‚ด๋ถ€์—์„œ ์‹คํ–‰ํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.


๋ทฐ ๋ฆฌ์กธ๋ฒ„

application-properties

spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

์Šคํ”„๋ง ๋ถ€ํŠธ๋Š” InternalResourceViewResolver ๋ผ๋Š” ๋ทฐ ๋ฆฌ์กธ๋ฒ„๋ฅผ ์ž๋™์œผ๋กœ ๋“ฑ๋กํ•œ๋‹ค.
์ด๋•Œ application.properties ์— ๋“ฑ๋กํ•œ spring.mvc.view.prefix , spring.mvc.view.suffix ์„ค์ • ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋“ฑ๋กํ•œ๋‹ค.

์Šคํ”„๋ง ๋ถ€ํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ๋ทฐ ๋ฆฌ์กธ๋ฒ„

  • BeanNameViewResolver : ๋นˆ ์ด๋ฆ„์œผ๋กœ ๋ทฐ๋ฅผ ์ฐพ์•„์„œ ๋ฐ˜ํ™˜
  • InternalResourceViewResolver : JSP๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ทฐ๋ฅผ ๋ฐ˜ํ™˜

1. ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ ํ˜ธ์ถœ
ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋ฅผ ํ†ตํ•ด ๋…ผ๋ฆฌ ๋ทฐ ์ด๋ฆ„์„ ํš๋“

2. ViewResolver ํ˜ธ์ถœ

new-form ์ด๋ผ๋Š” ๋ทฐ ์ด๋ฆ„์œผ๋กœ viewResolver๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ํ˜ธ์ถœ InternalResourceViewResolver ๊ฐ€ ํ˜ธ์ถœ๋จ

3. InternalResourceViewResolver

๋‚ด๋ถ€์—์„œ ์ž์›์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•œ๋‹ค.
์ด ๋ทฐ ๋ฆฌ์กธ๋ฒ„๋Š” InternalResourceView ๋ฅผ ๋ฐ˜ํ™˜

4. ๋ทฐ - InternalResourceView

InternalResourceView ๋Š” JSP์ฒ˜๋Ÿผ ํฌ์›Œ๋“œ forward() ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉ

5. view.render()

view.render() ๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  InternalResourceView ๋Š” forward() ๋ฅผ ์‚ฌ์šฉํ•ด์„œ JSP๋ฅผ ์‹คํ–‰ํ•œ๋‹ค

Thymeleaf ๋ทฐ ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•˜๋ฉด ThymeleafViewResolver ๋ฅผ ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค.
์ตœ๊ทผ์—๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ์Šคํ”„๋ง ๋ถ€ํŠธ๊ฐ€ ์ด๋Ÿฐ ์ž‘์—…๋„ ๋ชจ๋‘ ์ž๋™ํ™”ํ•ด์ค€๋‹ค.