학습(구)/Spring 요약

Spring - MVC

잉아당 2020. 10. 19. 16:54
728x90

스프링 MVC 설정 파일

설정이므로 @Configuration과 mvc설정인 @EnableWebMvc를 설정합니다. WebMvcConfigurer를 구현하는 클래스로 정의합니다. 이때 여러 디폴트 메소드들이 구현되어져 있으며 필요한 메소드만 재정의하여 사용합니다. 기본적으로 configureDefaultServletHandling메소드와 ConfigureViewResolvers메소드를 구현합니다. 전자는 매핑경로가 '/'일때 html/css 등을 처리해주기 위해 디폴트 서블릿을 설정하고 후자는 컨트롤러의 실행 결과를 보여주기 위해 뷰 리졸버에 관련된 설정을 해줍니다.

 

web.xml

WAS안에서 dispatcher가 생성될 때 같이 스프링 컨테이너도 생성이 됩니다. 이때 스프링 컨테이너 생성시 필요한 정보들을 <init-param>으로 전달합니다. contextClass의 이름으로 스프링 컨테이너 인터페이스를 설정하고 contextConfigLocation의 이름으로 스프링 설정 클래스를 지정합니다. <servlet-mapping>에 <servlet-name>을 생성한 서블릿으로 주고 <url-pattern>을 '/'으로 주어 해당 패턴의 요청들은 지정한 서블릿으로 처리하도록 설정합니다.

 

컨트롤러 : 웹 요청을 처리하고 그 결과를 뷰에 전달하는 Bean 객체

@Controller 어노테이션은 컨트롤러 역할 클래스로 지정하고 해당 클래스에서 @GetMapping, @PostMapping, @RequestMapping과 같은 요청 매핑 어노테이션으로 경로/방식을 지정하는데 서블릿 컨텍스트 경로가 기준이 됩니다. 지정한 대로 요청이 들어오면 요청 매핑 어노테이션이 붙은 메소드가 실행이 되는데 이때 비어있는 Model객체가 들어오고 요청 파라미터가 들어오는데 이때 @RequestParam 어노테이션을 사용하며 이 어노테이션은 요청 파라미터의 값을 지정한 메소드의 매개변수에 전달해주는데 required속성으로 필수 여부를 지정합니다. 메소드가 수행 되면 model에 key와 value가 추가되고 뷰 페이지 이름을 리턴해 줍니다. 핸들러 어댑터는 이를 통해 ModelAndView를 리턴해줍니다. 

컨트롤러는 Bean객체로 등록되어져야 합니다.

 

디폴트 핸들러

매핑 경로를 '/'로 설정한 dispatcher에서는 .jsp로 끝나는 요청을 제외한 모든 요청을 처리합니다.

@EnableWebMvc가 등록한 핸들러 매핑은 @Controller 어노테이션을 적용한 객체가 처리할 수 있는 요청 경로만 처리하고 나머지는 404에러로 처리합니다. 이를 해결하기 위해 스프링 MVC 설정 클래스에서 configurerDefaultServletHandling()메소드를 이용하여 디폴트 메소드를 설정합니다. 이 메소드는 매개변수로 DefaultServletHandlerConfigurer를 가지며 이 객체의 enable()메소드로 DefaultServletHttpRequestHandler와 SimpleUrlHandlerMapping. 객체를 Bean 객체로 등록합니다. 전자는 클라이언트의 모든 요청을 WAS가 제공하는 디폴트 서블릿에 전달하고 후자는 모든 경로를 DefaultServletHttpRequestHandler에서 처리하도록합니다. 매핑우선 순위는 @EnalbeWebMvc에서 설정한 RequestMappingHandlerMapping이 SimpleUrlHandlerMapping 보다 우선 순위가 높습니다.

 

1. RequestMappingHandlerMapping을 이용하여 요청을 처리할 핸들러를 검색하게 되는데 존재하면 이를 통해 처리합니다.

2. 존재하지 않으면 SimpleUrlHandlerMapping을 통해 요청을 처리할 핸들러를 검색하고 모든 경로에 대하여 DefaultSerletHttpRequestHandler를 리턴하여 디폴트 서블릿으로 처리합니다.

 

HandlerAdapter/HandlerMapping

HandlerAdapter와 HandlerMapping은 @EnableWebMvc에서 Bean 객체 등록을 자동으로 해줍니다. 이때 어댑터와 매핑에 해당하는 클래스가 있는데 RequestMappingHandlerMapping은 @Controller가 적용된 요청 매핑 어노테이션을 이용하여 요청을 처리할 컨트롤러 Bean을 찾습니다. RequestMappingHandlerAdepter는 컨트롤러의 메소드를 알맞게 실행하고 그 결과를 ModelAndView객체로 변환하여 서블릿에 리턴합니다.

 

ViewResolver

뷰리졸버는 스프링 MVC 설정 클래스에서 configurerViewReslvers()를 재정의하여 설정합니다.

이 메소드는 ViewResolverRegistry객체를 파라미터로 가지며 Registry.jsp메소드를 통해 jsp를 위한 뷰리졸버를 설정합니다. 내부적으로 InternalResourceViewResolver 객체를 사용하며 setPrefix()와 setSurfix()를 통해 prefix + 리턴된 뷰이름 + surfix의 경로를 뷰 코드로 사용하는 InternalResourceView객체를 리턴합니다. 이 뷰 객체가 jsp 페이지를 실행합니다.

 

Model

Model에 담긴 값은 View 객체에 Map형식으로 전달이 됩니다. InternalResourceView 객체는 전달 받은 Map 객체에 담긴 키값은 request.setAttribute를 통해 request의 속성에 저장하고 jsp에서 사용합니다.

 

JSP

컨트롤러가 보여주고자하는 뷰 코드입니다.

ModelAndView객체가 리턴이 되면 뷰리졸버가 해당 객체를 이용해서 처리하는데 스프링 MVC 설정 파일에서 설정한 configureViewResolver 메소드를 통해 실제 jsp파일을 찾고 처리합니다.  이때 jsp에서는 model 객체의 내용에 접근해서 사용할 수 있습니다. 이는 model 객체의 내용을 jsp가 접근할 수 있도록 HttpServletRequest에 옮겨주기 때문입니다.

 

전체 동작 방식

전체 동작 방식

사용자는 클라이언트로 요청을 전송합니다. 그러면 해당 요청은 DispatcherServlet(이하 DS)이 받고 DS은 요청 경로를 확인하고 이 요청 경로를 처리하는 컨트롤러가 어떤 것인지 프레임워크가 제공하는 HandlerMapping 객체에 요구하고 해당 객체는 요청 경로에 해당하는 컨트롤러 참조값을 리턴해 줍니다.

이 참조값을 통해 HandlerAdapter를 거쳐서 실행합니다. 이때 HandlerAdapter를 사용하는 이유는 요청 파라미터의 내용을 커맨드 객체로 타입 변환하여 자동으로 요청 파라미터의 내용이 어플리케이션에서 사용하는 커맨드 객체에 담기도록 수행하게 해주고 컨트롤러가 @Controller, Controller인터페이스, HttpRequestHandler 인터페이스 등 다양한 방법으로 작성되어도 수행할 수 있게 해주며 컨트롤러의 결과를 ModelAndView 객체로 만들어 주기 때문에 사용합니다.

이때 Model은 출력 문서에서 사용할 동적으로 생성되는 요소들에 대해 Map형태로 가지고 있는 것이고 View는 출력으로 수행할 뷰 페이지 이름을 가지고 있습니다. 이러한 이유로 HandlerAdapter를 사용하여 파라미터를 처리 후 컨트롤러가 실행되고 결과를 ModelAndView 객체를 생성하여 DS에 리턴합니다.

그 후 View 페이지를 동작시킬 객체를 만들거나 찾아야 하는 작업은 ViewResolver에 넘겨서 수행합니다. 이때 응답을 생성하기 위해 JSP를 사용하는 ViewResolver는 매번 새로운 View객체를 생성하여 DS에 리턴합니다.

ViewResolver에서는 이 작업을 수행하여 뷰 객체를 생성하고 DS은 뷰 객체에 jsp로 구현된 동적 문서를 수행하고 응답 문서를 생성해 브라우저에 전달하라고 명령합니다. 그럼 수행이 되어 생성된 문서를 몸통에 포함시켜 전달 됩니다.

 

컨트롤러와 JSP는 개발자가 직접 구현합니다.

컨트롤러, HandlerAdapter, HandlerMapping, ViewResolver는 Bean객체로 등록되어져 있어야합니다.

 

DispatcherServlet : 요청을 받는 창구 역할
HandlerMapping : 요청을 처리할 컨트롤러를 찾아서 리턴
Controller : 실제 요청을 처리하는 것
HandlerAdapter : 컨트롤러의 메서드 실행하고 결과를 무조건 ModelAndView로 리턴
ViewResolver : ModelAndView의 뷰이름을 통해 실제 뷰를 찾음
View : 응답을 생성할 JSP

 

Handler라고 하는 이유

스프림은 범용 프레임 워크 이고 컨트롤러는 다양한 방식으로 구현되기 때문에 웹 요청을 실제로 처리한 객체를 핸들러라고 합니다.

 

 

 

 

 

출처 : 가메출판사 - 스프링 5 - 최범균 저

'학습(구) > Spring 요약' 카테고리의 다른 글

Spring - 커맨드 객체  (0) 2020.10.19
Spring - 요청 경로 매핑과 요청 파라미터, 리다이렉트  (0) 2020.10.19
Spring - DB  (0) 2020.10.19
Spring - AOP  (0) 2020.10.18
Spring - Bean라이프사이클과 스코프  (0) 2020.10.16