실습 코드 참조
moonhy7/SpringFramework: Spring Framework 실습 코드 정리 (github.com)
5.1절 Spring MVC 수행 흐름
1. 스프링 MVC 수행 흐름
① 클라이언트로부터의 모든 .do 요청을 DispatcherServlet이 받는다.
② DispatcherServlet은 HandlerMapping를 통해 요청을 처리할 Controller를 검색한다.
③ DispatcherServlet은 검색된 Controller를 실행하여 클라이언트의 요청을 처리한다.
④ Controller는 비즈니스 로직의 수행 결과로 얻어낸 Model 정보와 Model을 보여줄 View 정보를 ModelAndView 객체에 저장하여 리턴한다.
⑤ DispatcherServlet은 ModelAndView로부터 View 정보를 추출하고 ViewResolver를 이용하여 응답으로 사용할 View를 얻어낸다.
⑥ DispatcherServlet은 ViewResolver를 통해 찾아낸 View를 실행하여 응답을 전송한다.
2. MVC 프레임워크
- Struts를 비롯한 대부분의 MVC 프레임워크는 비슷한 구조를 가졌기 때문에 하나의 프레임워크만 잘 이해해놓으면 다른 프레임워크도 이해하기 쉽다.
- 위 Spring MVC의 구조와 수행 흐름을 보면 현재 BoardWeb 프로젝트에 적용된 Controller 구조와 유사한 것을 알 수 있다.
- 유일하게 다른 하나는 Controller의 리턴 타입이 String 타입에서 ModelAndView로 바뀐 것이다.
5.2절 DispatcherServlet 등록 및 스프링 컨테이너 구동
1. DispatcherServlet 등록 ( _055_BoardWeb_Spring_MVC )
1) web.xml
- WEB-INF/web.xml 파일에 등록된 DispatcherServlet 클래스를 스프링 프레임워크에서 제공하는 DispatcherServlet으로 변경하기
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
2. 실행 결과
- login.jsp 파일을 실행하여 로그인을 시도하면 아래와 같이 콘솔에 출력된다.
- 서블릿 컨테이너는 클라이언트의 .do 요청이 있어야 Dispatcher 객체를 생성하므로 아직은 서블릿 컨테이너가 반응하지 않는다.
- 클라이언트가 login.do 요청을 서버에 전달하면 서블릿 컨테이너는 web.xml 파일에 action이라는 이름으로 등록된 DispatcherServlet 클래스의 객체를 생성한다.
2. 스프링 컨테이너 구동
1) DispatcherServlet
- 클라이언트의 요청으로 DispatcherServlet 객체가 생성되고 나면 DispatcherServlet 클래스에서 재정의된 init() 메소드가 자동으로 실행되어 XmlWebApplicationContext라는 스프링 컨테이너가 구동된다.
-XmlWebApplicationContext는 ApplicationContext를 구현한 클래스 중 하나이다.
- XmlWebApplicationContext는 우리가 직접 생성하는게 아니라 DispatcherServlet이 생성한다.
- 서블릿 컨테이너는 web.xml 파일에 등록된 DispatcherServlet만 실행해주고 HandlerMapping, Controller, ViewResolver 객체들은 DispatcherServlet가 스프링 컨테이너를 구동하여 생성되도록 한다.
- 우리가 직접 DispatcherServlet을 개발했을 때는 init() 메소드에서 객체들을 생성했고 스프링에서 제공하는 DispatcherServlet를 사용하면 스프링 컨테이너를 통해서 객체들을 생성하는 것이라는 차이점이 있다.
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private HandlerMapping handlerMapping;
private ViewResolver viewResolver;
public void init() throws ServletException {
handlerMapping = new HandlerMapping();
viewResolver = new ViewResolver();
viewResolver.setPrefix("./");
viewResolver.setSuffix(".jsp");
}
}
2) 스프링 컨테이너(XmlWebApplicationContext)의 구동 과정
- 서블릿 컨테이너가 DispatcherServlet 객체를 생성하고 나면 재정의된 init() 메소드가 자동으로 실행된다.
- 그러면 init() 메소드는 스프링 설정 파일(action-servlet.xml)을 로딩하여 XmlWebApplicationContext를 생성한다.(즉, 스프링 컨테이너가 구동되는 것이다.)
- 결국 스프링 설정 파일(action-servlet.xml)에 DispatcherServlet이 사용할 HandlerMapping, Controller, ViewResolver 클래스를 <bean> 등록하면 스프링 컨테이너가 해당 객체들을 알아서 생성해준다.
3. 스프링 설정 파일 등록
- DispatcherServlet은 Spring 컨테이너를 구동할 때 web.xml 파일에 등록된 서블릿 이름 뒤에 -servleet.xml 을 붙여서 스프링 설정 파일을 찾는다.
- DispatcherServlet이 스프링 컨테이너를 구동할 때 로딩할 스프링 설정 파일을 추가한다.
- WEB-INF 폴더에 action-servlet.xml 이라는 파일명의 파일을 생성한다.
5.3절 스프링 설정 파일 변경
1) 파일 이름 및 위치 변경
- DispatcherServlet은 자신이 사용할 객체들을 생성하기 위해 스프링 컨테이너를 구동한다.
- 이때 스프링 컨테이너를 위한 설정 파일의 이름과 위치는 서블릿 이름을 기준으로 자동으로 결정됨
- 필요에 따라 설정 파일의 이름을 바꾸거나 위치를 변경할 때는 서블릿 초기화 파라미터를 이용한다.
- WEB-INF 폴더에 이미 만들어놓은 action-servlet.xml 파일을 config 폴더(새로 만듬)에 옮기고 presentation-layer.xml으로 변경한다.
2) web.xml
- web.xml 파일의 DispatcherServlet 클래스를 등록한 곳에 <init-param> 설정을 추가한다.
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 이름에 따른 xml 파일이 아닌 다른 xml 파일을 읽도록 초기화 변수 설정 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/presentation-layer.xml</param-value>
</init-param>
</servlet>
- 이렇게 DispatcherServlet 를 설정하면 스프링 컨테이너가 DispatcherServlet 객체를 생성 한 후 아래와 같이 init() 메소드를 호출한다.
- 그리고 contextConfigLocation 이라는 파라미터로 설정한 정보를 추출하여 스프링 컨테이너를 구동할 때 사용한다.
3) 실행 결과
5.4절 인코딩 설정
1. 필터 클래스 추가
1) 이전에 만든 DispatcherServlet 클래스 인코딩 설정 확인
- 앞서 작성한 DispatcherServlet 클래스에서는 POST 방식의 요청에 적절하게 인코딩 처리를 하고 있다.
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
process(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//클라이언트에서 전송하는 데이터가 한글일 경우 깨짐 방지
request.setCharacterEncoding("UTF-8");
process(request, response);
}
}
2) CharacterEncodingFilter 등록하여 인코딩 처리
- 스프링에서 인코딩 처리를 위해 CharacterEncodingFilter클래스를 제공하며, web.xml 파일에 CharacterEncodingFilter 를 등록하면 모든 클라이언트의 요청에 대해서 일괄적으로 인코딩 처리할 수 있다.
- web.xml 파일에 CharacterEncodingFilter 클래스를 필터로 등록하는데, 필터는 엘리먼트 이름만 다를 뿐 서블릿과 거의 비슷하다.
- CharacterEncoding이라는 CharacterEncodingFilter 객체가 생성되고 <init-param> 으로 설정한 encoding 파라미터 정보를 읽어 인코딩 방식을 설정한다.
- <filter-mapping>에서 <url-pattern> 설정을 *.do로 했으므로 모든 클라이언트의 .do 요청에 대해서 CharacterEncodingFilter 객체가 일괄적으로 한글을 처리한다.
<filter>
<filter-name>characterEncoding</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>characterEncoding</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
댓글