반응형

1. 개요

실무 투입한지 거의 1년이 다 되어갈 무렵, web.xml 코드를 보던 중 문득 이런 생각이 들었다.

'웹 애플리케이션의 첫 단추인 web.xml에 대해 누군가에게 설명할 수 있을까?'  

1년간 일은 열심히 했는데 가장 기본적인것에 대한 공부가 전혀 안되있음을 느껴, 공부 후 포스팅을 한다.

참고로 web.xml에 대한 예제는 MVC 패턴 기준으로 작성했다.


2. 정의

web.xml은 DD (Deployment Descriptor : 배포 설명자)라고 불리며, Web Application의 설정파일이다.

DD는 Web Application 실행 시 메모리에 로드된다.

즉, web.xml이란 웹 어플리케이션을 실행시킬 때 함께 올라가야할 설정(설명)들을 정의해놓은 것이다.

그렇다면 web.xml에는 어떤 설정을 할까?


3. 설정

Web.xml 에서는 크게 DispatcherServlet, ContextLoaderListener, Filter 설정을 한다.

 

클라이언트의 요청을 처리하는 DispatcherServlet.

웹 어플리케이션 컨텍스트 단위의 설정을 로드하는 ContextLoaderListener,

이건 꼭 거쳤으면 좋겠네. Filter.

 

3.1) DispatcherServlet

DispatcherServlet은 클라이언트의 요청을 전달받는 객체이다. 하는 일은? 당연히 클라이언트의 요청을 처리하는 일이다. 그럼 어떻게 처리할까?

 

클라이언트의 요청을 처리하려면 크게 4가지 일이 진행되어야 한다.

 

첫째, 클라이언트의 요청을 처리해줄 컨트롤러를 찾는다.

둘째, 컨트롤러를 실행시킨다. (비지니스 로직 처리)

셋째, 클라이언트에게 보여질 View를 찾는다.

넷째, 응답 데이터와 View를 클라이언트에게 전달한다.

 

요청을 처리할 컨트롤러를 찾는 일은 Handler Mapping이라는 객체가 처리한다. 이 객체는 클라이언트의 요청 경로를 이용해서 컨트롤러를 검색하고, 검색된 객체를 DispatcherServlet에게 리턴한다.

만약 클라이언트가 'http://~~/test' 를 요청할 경우 /test를 처리할 컨트롤러 객체를 리턴하는 것이다. 

 

컨트롤러를 실행시키는 일은 Handler Adapter라는 객체가 처리한다. 이 객체는 @Controller 어노테이션을 이용해 구현한 컨트롤러 뿐만 아니라, Controller 인터페이스를 구현한 컨트롤러, 특수 목적으로 사용되는 HttpRequestHandler 인터페이스를 구현한 클래스를 동일한 방식으로 실행할 수 있도록 만들어졌다. (출처 : 스프링5 입문. 최범균)

즉, 컨트롤러 실행 업무에 특화된 객체로 Controller를 실행하는 것이다.

Controller가 실행되면 개발자가 구현한 비지니스 로직을 거쳐 응답 데이터가 추출된다. 실행된 Controller는 리턴할 데이터와 View를 Handler Adapter에게 리턴한다.

Handler Adapter는 데이터와 view를 ModelAndView 형태로 DispatcherServlet에게 리턴한다.

 

여기서 view는 단순히 view의 이름이다. 뭔 소리냐면 이 이름에 해당하는 실제 view를 찾아야한다는 것이다.

클라이언트에게 보여질 view를 찾는 일은 ViewResolver 객체가 처리한다.

ViewReolver bean 객체 설정

위는 viewResolver 객체를 설정하는 부분인데 설정된 prefix(접두사), suffix(접미사)를 참조하여 처리한다.

만약 Controller에서 리턴한 view 이름이 hello였다면 /WEB-INF/view/hello.jsp를 찾아 dispatcher Servlet에게 리턴한다.

 

최종적으로 viewResolver가 리턴한 View 객체에 응답 데이터를 넣어 클라이언트에게 리턴한다.

 

이처럼 클라이언트의 요청은 DispatcherServlet라는 감독관(?)이 처리한다. 다만 직접 처리하지 않고 적절한 객체들에게 일을 위임하여 처리하고 있다.

 

3.2) ContextLoaderListener

앞서 Dispatcher Servlet은 클라이언트의 요청을 처리하는 객체라고 설명했다. 웹 어플리케이션의 규모가 커진다면, 클라이언트의 요청또한 다양해질 것이고, 이를 처리할 Dispatcher Servlet도 늘어날 가능성이 있다. 다른 성격을 가진 서블릿이 생성될 것이고, 설정 또한 서블릿의 성격에 맞게 각각 적용시켜야 한다.

반면에, 모든 서블릿이 공통으로 가져야할 설정들도 있다. 즉 Servlet Context 단위가 아닌 Application Context 단위의 설정이 필요한데 이를 ContextLoaderListener 객체가 처리한다.

이 객체는 Application Context 단위의 설정을 생성한다.

참고로 Application Context 는 Web Application 의 Context이며, 모든 Servlet들이 참조가 가능한 부모 Context이다.

 

3.3) Filter

클라이언트에서 온 요청을 Dispatcher Servlet이 받기 전 거치는 부분이 있다. 바로 이 Filter 객체이다.

만약 스프링 시큐리티 필터가 적용되어 있다면, 인가 및 인증 처리를 먼저 처리하고, 인코딩 필터가 적용되어 있다면 클라이언트의 요청데이터를 인코딩하는 작업이 선 처리된 후 Dispatcher Servlet에게 필터링 된 데이터가 전달된다.


4. 예제

이제 나같은 코린이가 흔히 봤던... 그저 작성만 했던... web.xml 코드를 분석해보자

 

4.1) web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 
 <!-- Dispatcher Servlet 생성 -->
 <servlet>
     <servlet-name>myDispatcherServlet</servlet-name>
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
     <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath:/config/servlet-config.xml</param-value>
     </init-param>
     
     <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
     <servlet-name>myDispatcherServlet</servlet-name>
     <url-pattern>/</url-pattern>
 </servlet-mapping>
 
 <!-- web application context -->
 <listener>
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 <context-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>
         /WEB-INF/config/application-context.xml
     </param-value>
 </context-param>
 
 <!-- Encoding 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>
     <init-param>
         <param-name>forceEncoding</param-name>
         <param-value>true</param-value>
     </init-param>
 </filter>
 <filter-mapping>
     <filter-name>encodingFilter</filter-name>
     <url-pattern>/*</url-pattern>
 </filter-mapping>
</web-app>
cs

분석 전 다시 되새겨보겠다.

첫째, web.xml은 DD(Deploy Descriptor, 배포 설명자)이다.

둘째, DD는 Web Application 실행 시 메모리에 로드된다.

셋째, web.xml에는 크게 dispatcherServlet, contextLoaderListener, filter 를 설정한다.

 

만약 tomcat이라는 WAS(Web Application Server)를 통해 이 web Application을 실행시킨다고 가정하면, web.xml 파일에 설정한 내용들이 메모리에 로드될 것이다.

 

본격적으로 코드를 분석해보자.

 

7 ~ 16 line - 클라이언트의 요청을 처리하는 Dispatcher Servlet을 myDispatcherServlet이란 이름으로 생성하고, 이 서블릿에 대한 설정파일로 servlet-config.xml을 지정한다. (controller 스캔용, 코드는 글의 최하단에 첨부)

 

17 ~ 20 line - 설정한 Dispatcher Servlet이 처리할 url-pattern을 설정한다. '/' 경로로 들어오는 모든 요청에 대해서 myDispatcherServlet이 처리를 담당한다.

 

23 ~ 31 line - web application context 단위의 설정파일로 application-context.xml을 설정한다. 이 설정은 servelt으로 생성한 myDispatcherServlet에게 공유된다. (view-resolver 설정용, 코드는 글의 최하단에 첨부)

 

34 ~ 47 line - 스프링에서 지원하는 encoding Filter를 filter에 추가한다.

 

48 ~ 51 line - encoding Filter가 처리할 url-pattern을 설정한다. '/*' 모든 경로에 대해 인코딩 필터를 적용한다.

 

정리하면 이 예제 web.xml은 클라이언트의 요청을 처리할 인코딩 필터와 Dispatcher Servelt을 생성하고, view Resolver를 web application context 단위로 설정하였다.

 

> servlet-config.xml

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
 
 
    <context:component-scan base-package="controller"/>
    
</beans>
 
cs

 

> application-context.xml

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
 
cs

 

반응형
반응형

목차

1. 개요

2. 스프링이란?

3. POJO란?

4. MVC 패턴이란?

5. MVC 패턴 구조

 

1. 개요

 대부분 웹 개발자들은 JAVA를 사용한다. 많은 기능과 메소드를 제공할 뿐 아니라 분업에 최적회된 OOP 구조이기 때문이다. 하지만 그만큼 복잡하고 어렵고 무겁다. 이러한 무겁고 어려운 웹 개발을 보다 쉽게 하기 위해 등장한 프레임워크가 바로 스프링이다.


2. 스프링이란?

 Java EE의 복잡하고 어려운 사용을 단순화시킨 프레임워크이다. POJO 기반이며, MVC 패턴을 사용한다.


3. POJO란?

 POJO란 Plain Old Java Object의 약자로 그대로 해석하면 (보거나 이해하기)분명한 오래된 자바 객체라는 뜻이다.

 프로그래밍적 용어로 해석하면 복잡하고 어려운 Java라는 녀석을 이해하기 쉽고 가볍게 가공한 것이다.

 Java EE와 같은 기존의 "무거운" 객체를 만들게 된 것에 반발해서 사용되게 된 용어라고 한다.


4. MVC 패턴이란?

 MVC 패턴은 Model, View, Controller의 약자로 각각은 다음의 의미를 갖는다.

약자 원형 의미
M Model 데이터 및 데이터베이스와 관련된 비지니스 로직을 처리하거나 이를 조회, 조작하는 부분 
V View 유저 인터페이스를 정의하는 부분
C Controller 분업된 비지니스 로직 및 DB접근을 효율적으로 관리하고, View와 Model의 연결단 부분

Controller의 '연결단' 이라는 표현이 조금 모호할 수 있으나 MVC패턴의 구조를 보면 이해할 수 있을 것이다.


5. MVC 패턴 구조

 1) Client에서 URL(데이터)을 요청한다.

 

 2) Dispatcher Servlet은 적절한 Controller에게 요청을 전달해야 한다. 이는 Handler Mapping을 이용하여 처리한다.

 

 3) Controller는 board, user, menu 등 하나의 큰 작업단위이다. 그 작업단위를 세분화 시킨 것이 Service인데 앞서 말한것 처럼 Handler Mapping을 이용하여 전달받은 내용을 적절한 Service에게 전달한다.

 

 4) Service는 비지니스 로직을 실행하며 DB에 대한 접근이 필요할 시 DAO라는 ConnectionPool 객체를 호출한다.

 

 5) VO(Value Object)는 DTO(Data Transfer Object)라고도 하며 SQL 쿼리문 담아 DB를 조회, 조작할수 있다.

 

 6) DB 접근을 마치면 결과가 출력되는데 이를 View(.jsp)와 결합한 형태로 Controller에게 다시 전달한다.

 

 7) Dispatcher Servlet에게 위의 정보가 다시 전달되며 이는 View에 접근하여 완성된 View의 정보를 사용자에게 response한다. 단, 회원가입 및 정보 수정 같이 보안상 보여줄 필요가 없는 부분은 다른 View로 대체 가능하다.

 

그렇다면 앞서 말한 연결단은 Model과 View를 연결시키는 의미를 말하며 아래와 같이 정리가 가능하다

 

Controller = 'Model과정을 거친 데이터'+'View'

반응형

+ Recent posts