본문 바로가기
👨‍💻 2. 웹개발_Back end/2-6 Spring

[Spring] 5장 Spring MVC 구조 - ModelAndView를 이용한 서블릿 컨테이너 구동 및 한글 인코딩 처리 방식

by 달님🌙 2021. 10. 29.
반응형

 

실습 코드 참조

 

moonhy7/SpringFramework: Spring Framework 실습 코드 정리 (github.com)

 

GitHub - moonhy7/SpringFramework: Spring Framework 실습 코드 정리

Spring Framework 실습 코드 정리. Contribute to moonhy7/SpringFramework development by creating an account on GitHub.

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>

 

 

 

반응형

댓글