22.04.21 WIL Spring MVC 1

Seunghan·2022년 4월 24일
0

지난 WIL에서는 Web 기술과 Servlet이 어떻게 동작하는 지에 대하여 알아보았다.
이번 시간에서는 Spring이 어떻게 웹 개발과 관련된 기술을 지원하는지, 기존의 servlet을 사용하는 것과의 차이가 무엇인지를 잘 파악하면서 공부해보자!

Spring MVC

Spring Web MVCServlet API 를 기반으로 구축된 독창적인 웹 프레임워크

17. Web MVC framework

Front Controller Pattern

클라이언트에게 request를 받아서 decode하고 서비스를 실행하고, 알맞은 View로 변환하고 처리해야 할 게 너무많다. 이 과정을 통합적으로 처리 해 주는 부분을 template화 시켜놓고, 변경이 필요한 비즈니스 로직만 변경해 주는 건 어떨까?

Spring의 DispatchServlet이 이 front controller pattern을 통해 만들어 졌다.

Servlet Container and Spring Framework

DispatchServletservlet으로 부터 요청이 오면 handlerMapping,HandlerAdapter를 통해 알맞은 handler(controller)에 요청을 위임한 뒤, 비즈니스 로직을 실행하고 반환된 결과(ModelAndView)를 통해 ViewResolver를 통해서 View로 변환하는 기능 등을 통합적으로 처리해 준다.

Spring MVC 처리 흐름 (간단 version)

  1. DispatcherServlet의 HTTP 요청 접수
  2. DispatchServlet에서 Controller로 HTTP 요청 위임
  3. Controller의 모델 생성과 정보 등록
  4. Controller의 결과 리턴 : 주로 ModelAndView 반환
  5. DispatchServletView 호출(모델 참조)
  6. HTTP 응답 돌려주기

DispatchServlet

front controller pattern을 사용하여 DispatchServlet을 제일 앞단에다 두고, 요청을 받아서 등록되어 있는 다른 Handler(controller)들에게 호출할지 말 지를 결정하여 요청을 위임한다. 그리고 응답을 받아서 view를 만들어 내는 역할까지 한다.

DispatcherServlet은 Servlet와 마찬가지로 Javaconfiguration또는 web.xml을 사용하여 서블릿 규격에 따라 선언되고, 매핑되어야 한다.

Servlet Context 초기화 방법

Servlet Context를 초기화 하는 방법은 2 가지가 있다.

각각의 초기화 하는 방법과 설정해야 하는 정보들을 파악하며 공부해보자!

  • web.xml
  • WebApplicationInitializer

[spring] WebApplicationInitializer

DispatchServlet과 HandlerMapping

DispatchServlet에서는 핸들러 매핑 전략를 사용해 사용자 요청을 기준으로 어떤 핸들러에게 작업을 위임할지 결정한다.
DispatchServlethandlermapping을 순서대로 실행해서 handler를 찾고(ex @RequestMapping으로 요청이 온다면 RequestMappingHandlerMapping 이 실행된다) handleradapter를 조회한다.

실무에서는 99% 이상이 @RequestMapping을 사용한다!

Spring MVC - HandlerMapping의 동작방식 이해하기 1편

DispatchServlet과 HandlerAdapter

어떠한 핸들러가 처리할 지 결정되었다면 핸들러를 호출할 때 핸들러가 가지고 있는 메서드 파라미터에 맞게 시그니처를 변경해준다.

HTTPMessageConverter

뷰 템플릿으로 HTML을 생성해서 응답하는 것이 아니라, HTTP API처럼 JSON 데이터를 HTTP 메세지 바디에서 직접 익거나 쓰는 경우 HTTP 메세지 컨버터를 이용하는 게 좋다.

HttpMessageConverter는 HTTP 요청, HTTP 응답 둘 다 사용한다.

  • @ResponseBody
    - HTTP의 Body에 문자 내용을 직접 반환
    - viewResolver 대신 HTTPMessageConverter가 동작
    기본 문자 처리 : StringHttpMessageConverter, String 문자로 데이터 처리 1순위
    기본 객체 처리 : MappingJackson2HttpMessageConverter 개체 또는 HashMap? 2순위
    byte 처리 등등 여러 HttpMessageConverter가 기본으로 등록되어 있다. 0순위
  • @RequestBody
    @ResponseBody와 동일하게 동작

RequestMappingHandlerAdapter 동작 방식

위에서 HandlerAdapter가 각 handler의 메서드 시그니처에 맞게 변환해준다고 했는데 어떻게 가능할까?

출처 : https://www.inflearn.com/course/스프링-mvc-1

ArgumentResolversupportsParameter()를 호출해서 해당 파라미터를 지원하는지 체크하고, 지원하면 resolveArgument()를 호출해서 실제 객체를 생성한다. 그 후 컨트롤러로 넘어간다.
ReturnValueHandler도 마찬가지고 응답 값을 변환하고 처리한다.

가능한 파라미터 목록 - mvc-annarguments
가능한 응답값 목록 - mvc-annreturn-types

[spring] DispatcherServlet Flow

DispatchServlet과 ModelAndView

DispatchServlet은 컨트롤러에서 요청을 받아 응답을 받으면 ViewResolver를 통해 어떠한 View(jsp, thyme leaf)를 만들어 낼지 처리한다. 그 후 렌더링을 통해서 나온 결과를 response body에 실어서 client에 전달한다.

Spring MVC in Spring Professional Certification

DispatchServlet과 ViewResolver

SpringBoot는 InternalResourceViewResolver를 자동으로 등록한다.
이 때 apprication.propertiesspring.mvc.view.prefixspring.mvc.view.suffix를 변경하여 customize 할 수 있다.
InternalResourceViewResolver외에도 BeanNameViewResolver 등 다양한 viewResolver를 추가할 수 있다.

template 엔진이란?

WebMvcConfiguer

실제로 Spring이 필요한 대부분의 기능을 제공하기 떄문에 실제 기능을 확장할 일이 많지는 않다. 실제 기능 확장이 필요할 떄는 WebMvcConfiguer로 확장하자

[스프링 웹 MVC] WebMvcConfigurer 인터페이스

04. 웹과 관련된 설정

Static Resource 처리하기

Resource Handler

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를 추가할 수 있다.
}

2.5 리소스 핸들러 (default Servlet)

JSP

JSP는 현재 거의 쓰이지 않는다. 만약 레거시 프로젝트를 다루게 될때 한번 살펴보자

spring-boot-jsp/baeldung

profile
주니어 백엔드 개발자입니다!

0개의 댓글