MVC(Model-View-Controller) 패턴은 웹 어플리케이션 개발에서 사용자의 요청을 처리하고 적절한 결과를 반환하기 위한 구조입니다.

Spring MVC의 DispatcherServlet을 등록하고 url 매핑을 설정
<servlet> : DispatcherServlet의 초기화를 정의<servlet-mapping> : url 패턴과 서블릿을 연결여기서는 DispatcherServlet을 설정하여 .do로 끝나는 모든 url 요청을 action이라는 이름의 servlet이 처리하도록 지정합니다.
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/egovframework/springmvc/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
이 설정 부분을 좀 더 알아보자면,
DispatcherServlet은 MVC 패턴에서 핵심적인 역할을 수행하는 서블릿으로 주요역할은 다음과 같다.
참고
Controller가 반환하는 결과는 View이름, JSON 데이터, 파일, 리다이렉트 URL등 다양한 형태일 수 있습니다.
View이름이 아닌 데이터를 반환할 경우,ViewResolver는 동작하지 않습니다.
<servlet> 설정은 DispatcherServlet이 제대로 동작할 수 있도록 필수적인 초기 설정을 제공합니다.
<servlet-name>
<servlet-mapping> 태그에서 사용됨. (위에서는 action 이라는 이름으로 DispatcherServlet을 등록)<servlet-class>
org.springframework.web.servlet.DispatcherServlet을 사용하여 Spring MVC의 요청 처리 흐름을 담당합니다.<init-param>
서블릿 초기화 시 필요한 추가 설정 정의
<param-name>은 초기화 매개변수 이름 정의
contextConfigLocation이라는 이름이 사용되었고, 이는 Spring MVC에서 Spring의 어플리케이션 컨텍스트(Application Context)를 구성하기 위한 XML파일의 경로를 지정하는 표준 이름임<param-value>는 <param-name>에서 지정한 매개변수의 값을 설정
/WEB-INF/config/egovframework/springmvc/dispatcher-servlet.xml 로 경로를 지정했고, 이 경로에 있는 XML파일은 Spring MVC 어플리케이션의 설정 정보를 포함한다.<load-on-startup>
<servlet-mapping> 설정은DispatcherServlet에 매핑된 URL 패턴을 정의한다. 이 매핑은 특정 URL 요청이 해당 서블릿에서 처리되도록 설정하는 것이다.
<servlet-name>
<url-pattern>
동작 흐름 연계
- DispatcherServlet이 초기화 되면서
<init-param>에서 지정된 XML파일을 로드
- 이 파일에 정의된 설정을 파탕으로 Controller, ViewResolver, HandlerMapping 등이 구성됨
- 구성되 Spring 어플리케이션 컨텍스트를 통해 모든 요청 처리가 이루어짐
다시 위의 코드를 보면
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/egovframework/springmvc/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>은 .do로 끝나는 url은 action이라는 이름을 가지는 servlet이 처리하게끔 설정해두었습니다.
그래서 action 이라는 이름의 servlet에 사용자의 요청이 전달되고
이 action servlet은 DispathcerServlet클래스를 사용합니다.
DispathcerServlet은 init-param 을 통해서 설정파일을 설정하고, 설정파일의 경로는 다음과 같습니다.
INF/config/egovframework/springmvc/dispatcher-servlet.xml
그리고 이 Spring MVC 설정파일의 위치는 contextConfigLocation 라는 초기화 매개변수를 통해서 찾을 수 있습니다.
마지막으로 <load-on-startup>이 1이어서 애플리케이션 시작 시점에 서블릿이 초기화됩니다.
다음의 경로로 접근하면, INF/config/egovframework/springmvc/dispatcher-servlet.xml
이 파일은 servlet의 설정에 관한 부분이다.
<context:component-scan base-package="egovframework">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
그리고 여기서 Controller를 Bean으로 등록한다.
Controller 클래스를 new로 생성하지 않아도
component-scan을 통해 bean으로 등록하고 사용할 수 있게 됩니다.
위 코드를 보면, Controller 부분만 include-filter된 것을 확인 가능
자동생성 되어있는 web패키지로 이동하면
다음은 RequestMappingHandlerAdapter와 RequestMappingHandlerMapping을 통해서 Controller클래스에서 @RequestMapping 어노테이션을 지원해주게 됩니다.
@Controller
public class EgovSampleController {
.
.
.
/**
* 글 등록 화면을 조회한다.
* @param searchVO - 목록 조회조건 정보가 담긴 VO
* @param model
* @return "egovSampleRegister"
* @exception Exception
*/
@RequestMapping(value = "/addSample.do", method = RequestMethod.GET)
public String addSampleView(@ModelAttribute("searchVO") SampleDefaultVO searchVO, Model model) throws Exception {
model.addAttribute("sampleVO", new SampleVO());
return "sample/egovSampleRegister";
}
.
.
.
}
이 코드를 살펴봅시다.
"/addSample.do" 이 url을 요청하면
RequestMapping과 연결된 아래쪽의 함수가 실행됩니다.
이후
사용자의 요청을 기반으로 비지니스 로직을 처리하고 데이터베이스와 데이터를 교환하거나 데이터를 가공하여 사용자에게 결과를 반환하게 되는데, 아직은 패스~
그리고 return "sample/egovSampleRegister"; 를 보면 알 듯 "sample/egovSampleRegister"라는 jsp파일 이름을 리턴합니다.
WEB-INF > jsp > egovframework > example > sample 을 보면 있는 egovSampleRegister 라는 jsp 파일을 볼 수 있는데,

이를 보여줄 수 있는 이유는,
"sample/egovSampleRegister"를 리턴할 때
dispatcher-servlet.xml 에 있는 ViewResolver클래스의 도움을 받기 때문입니다.
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" p:order="1"
p:viewClass="org.springframework.web.servlet.view.JstlView"
p:prefix="/WEB-INF/jsp/egovframework/example/" p:suffix=".jsp"/>
이 클래스도 bean으로 등록이 되어있는 상태이고 prefix로 WEB-INF/jsp/egovframework/example/ 다음과 같은 경로가 설정되어 있어서
우리는 리턴할 때 위의 경로를 생략할 수 있는 것임.
프레임워크는
이 경로를 따라가서 명시된 경로 밑에서부터 jsp파일을 찾습니다. 그리고 controller에서 요청된 jsp파일을 찾아 연결해줍니다.
즉, ViewResolver의 도움을 받아 적절한 페이지를 보여주는 것!
지금 src > main > java 에
egov_main.web 이란 패키지에
MainController 라는 클래스 생성

여기에 어노테이션을 걸면
새로 생성한 egov패키지 밑에서부터 이런 어노테이션을 찾고
bean으로 등록하기 위해 다시 dispatcher-servlet으로 이동해서
아래와같이 수정한다.
<context:component-scan base-package="egov"> //이부분
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
그러면, egov 패키지 밑의 controller만 bean으로 등록된다.
이전에는 <context:component-scan base-package="egovframework">
였는데, 그럼 이제는egovframework 패키지 밑에 있던 컨트롤러는 bean으로 등록이 안 됨.
그리고 이 부분도 prefix를 수정해준다.
그러면 /WEB-INF/jsp/ 밑에서 부터 jsp파일을 찾는다.
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" p:order="1"
p:viewClass="org.springframework.web.servlet.view.JstlView"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
그리고 컨트롤러를 다음과 같이 작성해보자.
package egov_main.web;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class MainController {
@RequestMapping(value="/main.do")
public String main (HttpServletRequest request, ModelMap model) {
return "main/main";
}
}
HttpServletRequest 이 파라미터는 사용자가 입력한 값을 받을 수 있는 파라미터임.
예를 들어 로그인 할때 입력한 아이디, 패스워드
ModelMap url을 요청한 사용자에게 데이터를 전달할 때 사용
return "main/main"; 이렇게 return이후에 넣는 값은 리턴할 jsp파일의 경로인데
위에 p:prefix="/WEB-INF/jsp/ 이후의 경로를 작성해 주면 된다.
서비스 클래스 환경설정을 해 보자
web.xml을 열어 context-param 의 경로 부분을 확인해보자
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:egovframework/spring/context-*.xml</param-value>
</context-param>
위의 경로를 따라가면 context-.xml 파일이 여러개 있다

이 파일들은 Dispatcher Servlet이 초기에 사용하는 설정 파일이다.
context-common.xml 을 확인해 보면, 앞서 dispatcher-servlet에서 보았더 내용과 동일한 내용이 있다.
다만 여기서는 exclude-filter 을 통해 controller 어노테이션을 제외한 나머지 어노테이션을 지원해준다.
여기서 새로 만든 egov패키지에서 어노테이션을 찾게 하기 위해서 base-package를 egov로 변경해준다.
<context:component-scan base-package="egov">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
spring에서 모르는 태그 설명 찾는 방법은 이쪽으로
이런 설정을 통해서 @Service 등의 어노테이션이 egov 로 시작하는 패키지에서 사용 시 자동으로 빈을 등록해주게 할 수 있다
그런데 이러한 class들은 생성한 적이 없는데 어떻게 동작할까?
pom.xml에 가면 스프링이 동작하기위해 필요한 라이브러리들을 볼 수 있다.

이미 이런 라이브러리들이 다운받아져 있기때문에 스프링 프레임워크가 동작을 하는 것이다
전자정부프레임워크는 이미 라이브러리들이 다운받아져있지만,
순수 스프링에서는 pom.xml에 사용할 라이브러리를 적어주고 다운을 해야한다.