Spring MVC framework

MisCaminos·2021년 3월 11일
1

Server & Web

목록 보기
13/23
post-thumbnail

spring MVC의 주요 구성 요소

Dispatcher Servlet

Dispatcher Servlet = Controller라고 생각하면됨.
Controller의 역할(Action 즉 backend controller의 역할)을 Dispatcher Servlet이 하는 것이다.

  • Servlet class이며, 모든 client의 요청을 처리한다.
  • Controller(Action)에게 client의 요청을 전달하고, Controller가 리턴한
    결과값을 View에 전달하여 알맞은 응답을 생성하도록 한다.

HandlerMapping

Client의 요청 URL(또는 URI)을 어떤 Controller(Action)가 처리할지는 결정한다.
(요청 URL과 Controller 클래스의 mapping을 관리한다. (이전 Dynamic Web Project 실습에서 config.properties 파일을 통해 command = 처리(.do = Action(클래스) or .do = action(메소드))가 define된대로 client 요청과 처리 action이 연결되었던것과 같음)

클래스들을, 또는 클래스내의 메소드들을 mapping할 수 있다.

Controller(Action)

controller의 back-end 부분.
클라이언트의 실질적인 요청을 처리한다. Model(DAO, DTO, etc) 처리 결과를 Model결과에 담아서 DispatcherServlet에 반환 (Model 또는 ModelandView에 처리한 결과를 저장한다.)

Model(AndView)

Controller(Action)가 모델의 처리한 결과 정보를 view에 담는다

ViewResolver

ViewResolver는 Spring이 제공해준다. ViewResolver는 view를 찾는 객체이다.
여러 view를 선택 할 수 있도록해준다. (e.g., template이 있다면, template을 사용)
view 종류별로 ViewResolver가 필요하다. 각 ViewResolver가 각 view를 처리한다.

  • Controller(Action)의 처리 결과를 생성할 뷰를 결정한다.
  • Controller가 리턴한 View이름으로 실행될 JSP경로 완성

View

Controller(Action)의 처리 결과 화면을 생성, 출력데이터를 설정

Spring MVC 실습

Spring Legacy Project를 하나 생성해서 spring framework를 활용한 MVC 패턴을 구현해보았다.

File > New > Spring Legacy Project > Spring MVC Project

Java Resources/src/main/java 폴더에 DAO, DTO, Controller, Utility등의 Java class들이 들어가고
src/main/webapp/WEB-INF/views 폴더에는 view jsp 파일들이 들어간다.
src/main/webapp/WEB-INF/spring 폴더에는
root-context.xml, bbs.xml, servlet-context.xml 과 같은 설정 파일들이 들어간다.
그리고 맨 아래에 pom.xml에서는 spring version과 같은 기반이 되는 조건들을 설정하기 위한 properties(java version, spring framework version, etc), dependencies(maven repository에서 가져오는 artifact, file upload setting, etc), plugin과 같은 요소들을 설정한다.

Spring의 MVC 처리 순서


1. client 요청이 DispatcherServlet에게 전달된다.
2. DispatcherServlet은 HandlerMapping을 사용해서 client요청을 처리할 Controller 객체를 추출한다.
3. Controller에서 model을 사용하여 client의 요청을 처리한다.
4. Controller는 처리결과 data를 Model(AndView)에 담아서 return한다.
5. DispatcherServlet은 ViewResolver로부터 응답결과를 생성할 view 객체를 추출한다.
6. View는 client에게 전송할 응답이다.

설정 파일들(.xml)

이렇게 dispatcherServlet을 중심으로 요청처리가 되도록 설정하는 xml 파일들에 대해 정리해보았다.

제일 먼저 시작하는 위치는 서블릿컨테이너 설정파일인 WEB-INF/web.xml이다. web.xml에서 client의 요청을 전달받고, model을 access해서 요청을 처리 할 Dispatcher Servlet을 설정한다. 그리고 application 공통으로 사용 할 application-context를 설정한다.

note: 큰 project의 경우 DispatcherServlet을 여러개 선언해야할때도 있다. 각 DispatcherServlet이 각자의 설정파일을 통해 정보를 설정하게되는데 dispatcherServlet들이 공통적으로 설정하는 부분도 다 각각 설정파일과 연결하면 너무 비효율적이다. 그래서 최상위 설정파일을 하나 만들어서 공통으로 정보 설정한다. (e.g., web.xml안에 < context-param >과 < listener >)

web.xml:

<web-app>
....
<!-- 1. 클라이언트의 요청을 전달받을 DispatcherServlet 설정 -->
<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<!-- 2. 공통으로 사용할 resources 설정 -->
<!-- The definition of the Root Spring Container shared by all Servlets 
    and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>
....
</web-app>

web.xml에서 Dispatcher Servlet의 설정파일로 /WEB-INF/spring/appServlet/ 경로의servlet-context.xml이 지정되었고, application 공통으로 사용 할 resources를 설정하는 곳으로 root-context.xml이 지정되었다.

각각의 설정 파일을 들여다보면,

servlet-context.xml에서 Context를 생성한다. Context는 스프링이 사용하는 메모리 영역이고 스프링 프레임워크가 시작되면서 생성된다. 스프링에선 ApplicationContext라는 이름의 객체가 만들어진다. 스프링에서는 자신이 객체를 생성하고 관리해야 하는 객체들에 대한 설정을 servlet-context.xml 파일에 담는다.

servlet-context.xml파일에 설정되어 있는 <context:component-scan>에 지정되어 있는 패키지를 스캔(scan)하고, 해당 패키지의 있는 클래스들 중에서 스프링이 사용하는 @Component (또는 필요시 @Controller) 가 선언된 클래스의 객체를 생성한다.

그리고 servlet-context.xml에서 기본적인 viewResolver 역할을 할 viewResolver객체를 설정 한다. 아래 servlet-context.xml 파일 내용을 보면 WEB-INF/views 폴더안에 있는 jsp 파일들을 찾도록 설정되어있다. 그런데 viewResolver property name=order에 값이 2로 지정되어있다. servlet-context에 있는 viewResolver를 2순위로 viewPage를 찾는데에 사용하라고 설정을 해둔것이다. 그럼 1순위는?

servlet-context.xml:

<!-- DispatcherServlet Context: defines this servlet's request-processing 
		infrastructure -->

   <!-- Enables the Spring MVC @Controller programming model -->
	<mvc:annotation-driven />

   <!-- Handles HTTP GET requests for /resources/** by efficiently serving 
		up static resources in the ${webappRoot}/resources directory -->
   <!-- mapping="/**" 는 webapp안에 모든것을 다 가져다 쓸수있다는 의미임. -->
	<mvc:resources mapping="/**" location="/" />
    
    <!-- view page를 찾는 ViewResolver -->
    <!-- Resolves views selected for rendering by @Controllers to .jsp resources 
    		in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
		<beans:property name="order" value="2" />
	</beans:bean>
	
    <!--Application Context 객체 생성을 위한 설정. 어느 package를 보면되니? -->
	<context:component-scan base-package="spring.sts.webtest" />
	<context:component-scan base-package="spring.model.bbs" />

root-context.xml를 들여다보면 찾을 수 있다. root-context.xml에서 application의 모든 web component들이 함께 공유하는 resources를 정의하는데, 여기에 resources중 하나로 tiles2가 1순위로 view page를 지정하도록 명시해둔다.

아래 코드를 보면, tilesconfigurer이라는 bean을 정의하고 tiles2 값을 가지고있는 viewResolver bean을 정의해서 1순위 viewResolver 역할을 수행하도록 한다.

여러개의 view page 관리를 위해 tiles을 사용할때, 이와 같이 설정하고 요청 url과 view page를 mapping하는 xml파일을 (주로 DB 테이블 별로 나누어서) webapp/WEB-INF/spring 경로에 생성한다. 그리고 tiles mapping 역할을 하는 xml 파일 경로를 tiles configurer안에 지정한다.

root-context.xml:

<beans>
....
<!-- tiles2 설정 -->
<bean id="tilesconfigurer"
      class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
	<property name="definitions">
	   <list>
	      <value>/WEB-INF/spring/bbs.xml</value>
	      <value>/WEB-INF/spring/member.xml</value>
	   </list>
	</property>
</bean>
<bean id="viewResolver"
		class="org.springframework.web.servlet.view.UrlBasedViewResolver">
	<property name="viewClass">
	   <value>org.springframework.web.servlet.view.tiles2.TilesView</value>
	</property>
	<property name="order" value="1"></property>
</bean>
....
</beans>

root-context.xml에는 tiles2 설정 외에도, DB 접속 설정내용, MyBatis SQL 실행 설정내용 & mapper xml DAO interface설정, file upload전용 설정내용, spring과 JPA 연동 등등

application의 web component들이 공유하는 resource들의 설정 정보를 담는다.

그리고 추가적으로 web.xml에는 encoding을 처리하는 filter을 설정할 수 있다. 여기서 filter는 client와 server사이에서 request와 response가 오갈때 상대방쪽에 전달되기 전에 intercept해서 character encoding, 보안, logging, data compression, 등의 목적으로 filter를 거치게하는 것이다. (filter와 intercept에 대해서는 더 자세하게 다음 시간에...)

위에서 이미 설명한 web.xml 설정 부분 두가지 이외에 한글 encoding을 처리하는 부분을 추가한다.
(1) 클라이언트의 요청을 전달받을 DispatcherServlet 설정 (위에서 설명했던)
(2) 공통으로 사용할 애플리케이션 resources 설정 (위에서 설명했던)
그리고,

(3) 한글처리용 필터(filter) 설정 (e.g., < filter >, < filter-mapping>)
filter (요청되기전/ 응답되기전 낙아채서! 검증하는 역할을 한다. 보안, encoding, 등의 이슈에 대한 filter처리를 할 수 있다.

web.xml:

<web-app>
....
	<!-- (3) 한글 처리용 filter -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>
			org.springframework.web.filter.CharacterEncodingFilter
		</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

각 xml파일들이 무엇을 설정하는지 알게되니, 아래 그림이 좀 더 이해가 된다.

아래 그림에는 spring framework이 기본적으로 제공하는 것(파란색), 개발자가 직접 만드는 것(보라색), 주로 spring framework이 제공하지만 개발자가 수정할수도 있는 것(초록색)으로 각각의 역할이 구분되어있다.



References:
  1. 스프링 MVC의 주요 구성 요소 from lectureblue

  2. web.xml vs. Initializer with Spring from Baeldung

profile
Learning to code and analyze data

0개의 댓글