지난 WIL에서는 Web 기술과 Servlet이 어떻게 동작하는 지에 대하여 알아보았다.
이번 시간에서는Spring
이 어떻게 웹 개발과 관련된 기술을 지원하는지, 기존의servlet
을 사용하는 것과의 차이가 무엇인지를 잘 파악하면서 공부해보자!
Spring Web MVC는 Servlet API 를 기반으로 구축된 독창적인 웹 프레임워크
클라이언트에게 request
를 받아서 decode하고 서비스를 실행하고, 알맞은 View
로 변환하고 처리해야 할 게 너무많다. 이 과정을 통합적으로 처리 해 주는 부분을 template
화 시켜놓고, 변경이 필요한 비즈니스 로직만 변경해 주는 건 어떨까?
Spring의 DispatchServlet
이 이 front controller pattern
을 통해 만들어 졌다.
Servlet Container and Spring Framework
DispatchServlet
은 servlet
으로 부터 요청이 오면 handlerMapping
,HandlerAdapter
를 통해 알맞은 handler(controller)에 요청을 위임한 뒤, 비즈니스 로직을 실행하고 반환된 결과(ModelAndView
)를 통해 ViewResolver
를 통해서 View
로 변환하는 기능 등을 통합적으로 처리해 준다.
DispatcherServlet
의 HTTP 요청 접수DispatchServlet
에서 Controller
로 HTTP 요청 위임Controller
의 모델 생성과 정보 등록Controller
의 결과 리턴 : 주로 ModelAndView
반환DispatchServlet
의 View
호출(모델 참조)front controller pattern
을 사용하여 DispatchServlet
을 제일 앞단에다 두고, 요청을 받아서 등록되어 있는 다른 Handler(controller)
들에게 호출할지 말 지를 결정하여 요청을 위임한다. 그리고 응답을 받아서 view
를 만들어 내는 역할까지 한다.
DispatcherServlet은 Servlet와 마찬가지로
Javaconfiguration
또는web.xml
을 사용하여 서블릿 규격에 따라 선언되고, 매핑되어야 한다.
Servlet Context를 초기화 하는 방법은 2 가지가 있다.
각각의 초기화 하는 방법과 설정해야 하는 정보들을 파악하며 공부해보자!
[spring] WebApplicationInitializer
DispatchServlet
에서는 핸들러 매핑 전략를 사용해 사용자 요청을 기준으로 어떤 핸들러에게 작업을 위임할지 결정한다.
DispatchServlet
은 handlermapping
을 순서대로 실행해서 handler
를 찾고(ex @RequestMapping
으로 요청이 온다면 RequestMappingHandlerMapping
이 실행된다) handleradapter
를 조회한다.
실무에서는 99% 이상이 @RequestMapping을 사용한다!
Spring MVC - HandlerMapping의 동작방식 이해하기 1편
어떠한 핸들러가 처리할 지 결정되었다면 핸들러를 호출할 때 핸들러가 가지고 있는 메서드 파라미터에 맞게 시그니처를 변경해준다.
뷰 템플릿으로 HTML을 생성해서 응답하는 것이 아니라, HTTP API처럼 JSON 데이터를 HTTP 메세지 바디에서 직접 익거나 쓰는 경우 HTTP 메세지 컨버터를 이용하는 게 좋다.
HttpMessageConverter
는 HTTP 요청, HTTP 응답 둘 다 사용한다.
@ResponseBody
viewResolver
대신 HTTPMessageConverter
가 동작StringHttpMessageConverter
, String
문자로 데이터 처리 1순위MappingJackson2HttpMessageConverter
개체 또는 HashMap
? 2순위byte
처리 등등 여러 HttpMessageConverter
가 기본으로 등록되어 있다. 0순위@RequestBody
@ResponseBody
와 동일하게 동작위에서 HandlerAdapter
가 각 handler
의 메서드 시그니처에 맞게 변환해준다고 했는데 어떻게 가능할까?
출처 : https://www.inflearn.com/course/스프링-mvc-1
ArgumentResolver
의 supportsParameter()
를 호출해서 해당 파라미터를 지원하는지 체크하고, 지원하면 resolveArgument()
를 호출해서 실제 객체를 생성한다. 그 후 컨트롤러로 넘어간다.
ReturnValueHandler
도 마찬가지고 응답 값을 변환하고 처리한다.
가능한 파라미터 목록 - mvc-annarguments
가능한 응답값 목록 - mvc-annreturn-types
[spring] DispatcherServlet Flow
DispatchServlet
은 컨트롤러에서 요청을 받아 응답을 받으면 ViewResolver
를 통해 어떠한 View(jsp, thyme leaf)
를 만들어 낼지 처리한다. 그 후 렌더링을 통해서 나온 결과를 response body
에 실어서 client에 전달한다.
Spring MVC in Spring Professional Certification
SpringBoot는 InternalResourceViewResolver
를 자동으로 등록한다.
이 때 apprication.properties
의 spring.mvc.view.prefix
와 spring.mvc.view.suffix
를 변경하여 customize 할 수 있다.
InternalResourceViewResolver
외에도 BeanNameViewResolver
등 다양한 viewResolver
를 추가할 수 있다.
실제로 Spring이 필요한 대부분의 기능을 제공하기 떄문에 실제 기능을 확장할 일이 많지는 않다. 실제 기능 확장이 필요할 떄는 WebMvcConfiguer
로 확장하자
[스프링 웹 MVC] WebMvcConfigurer 인터페이스
HTML, CSS, Javascript, image 등 정적 resource을 처리해주는 핸들러
기본적으로 Servlet Container
(톰캣, 제티, 언더토우 등등)에는 정적인 자원을 처리할 수 있는 Default Servlet
이 등록되어 있다. 그렇기 때문에 프로젝트를 생성하고 아무 설정을 하지 않더라도 Resource
요청을 하면 동작이 된다. 하지만 만약 특정 요청에 대해 Resource
를 Control 할 필요가 있다면 ResourceHandler
를 정의해서 Config
에 등록해줘야한다.
web 설정과 관련된 WebMvcConfiguer
를 상속받으면 쉽게 resourceHandler
관련 기능을 추가할 수 있다. + Spring의 Resource
를 다루는 부분과 잘 연계해서 보자!
@EnableWebMvc
@Configuration
static classAppConfigimplementsWebMvcConfigurer,ApplicationContextAware{
ApplicationContextapplicationContext;
@Override
publicvoidaddResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")// 해당 URI 경로에 대해서 요청이 오면
.addResourceLocations("/resources/")// 여기서 resource를 찾아라
.setCachePeriod(60) // 캐시는 60초로 해 놓을 것이다!
.resourceChain(true)
.addResolver(newEncodedResourceResolver());// resolver는 기본적으로 path와 관련된 resolver가 default지만 encoding이나 특정 파일을 매핑할 수 있게 해주는 resolver를 추가할 수 있다.
}
JSP는 현재 거의 쓰이지 않는다. 만약 레거시 프로젝트를 다루게 될때 한번 살펴보자