개발/Spring Framework

[Spring Framework] 스프링 MVC 프로젝트의 구조

백괴 2020. 10. 13. 20:57

우리는 이전 강좌에서 스프링 MVC 모델에 대해 알아보았습니다.

위의 각각의 컴포넌트들은 스프링 프로젝트의 XML 및 Java 파일들로 구현됩니다.

본 강좌에서는 이를 바탕으로, 실제 스프링 MVC 프로젝트의 구조를 알아보겠습니다.

 

스프링 프로젝트의 구조

스프링 프로젝트 생성 시 나타나는 기본 구조

1. Dispatcher-Servlet  설정

Dispatcher-Servlet은 web.xml(웹 설정 파일)에서 정보를 명시한 다음 스프링을 구동할 때 구현됩니다.

 

web.xml

<?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">

	<!-- 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>

	<!-- 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>
		
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

 

<servlet> 태그는 Dispatcher-Servlet을 구현하는 데 필요한 클래스, 초기 파라미터 정보 등을 포함합니다.

 

하위 태그들의 정보는 다음과 같습니다.

  • <servlet-name> : 서블릿의 이름을 지정합니다.
  • <servlet-class> : Dispatcher-Servlet을 구현하기 위한 클래스를 지정합니다.
  • <init-param> : 초기 파라미터 정보를 포함합니다. <param-value> 태그를 통해 서블릿 환경 설정 파일의 경로를, <param-name> 태그를 통해 사용될 이름을 명시할 수 있습니다.
  • <load-on-startup> : 서버가 시작될 때, 해당 서블릿에 대한 최초 요청 시의 초기화 우선 순위를 부여합니다. 0보다 큰 값이면서 숫자가 낮을수록 우선입니다.

<servlet-mapping> 태그는 <url-pattern> 태그에서 명시한 대로 서블릿에 대한 요청이 들어오면, <servlet-name> 태그에 명시한 이름의 서블릿으로 요청을 보냅니다.

 

2. 스프링 서블릿 환경 설정 파일

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- 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:bean>
	
	<context:component-scan base-package="com.uncyclocity.practice" />
	
	
	
</beans:beans>
  • <annotation-driven> : @Controller 어노테이션을 인식하여 클래스를 컨트롤러로 등록할 수 있도록 합니다.
  • <resources> : html, jsp 등의 웹 문서의 정보를 명시합니다.
  • <beans:bean> : 컨트롤러가 모델을 리턴하여 DIspatcher-Servlet이 이를 토대로 JSP파일을 찾을 때 사용되는 정보를 명시합니다. 상단의 코드의 경우 "/WEB-INF/views/" 경로에서 반환된 문자열 값과 동일한 이름의 JSP 파일을 찾습니다.
  • <context:component.scan> : Java 파일의 @Component 어노테이션류(@Bean, @Controller 등)로 등록된 Bean 객체를 찾도록 도와줍니다.

3. 컨트롤러 및 JSP 파일

home.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>
	Hello world!  
</h1>

<P>  The time on the server is ${serverTime}. </P>
</body>
</html>

HomeController.java

@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
}
  1. @Controller 어노테이션으로 컨트롤러임을 명시해 주었습니다. 서블릿 환경설정 파일의 <annotation-driven> 태그가 이를 인식하여 클래스를 컨트롤러로 등록합니다.
  2. HandlerMapping에 의해 결정된 컨트롤러에서 HandlerAdapter에 의해 실행 메소드가 결정되며, @RequestMapping 어노테이션을 통해 실행 메소드 정보를 제공받습니다. value 값에 해당하는 URL이 GET 방식으로 요청이 들어오면 해당 메소드를 실행합니다.
  3. model의 addAttribute 메소드를 통해 'serverTime'이라는 이름의 매개 변수에 현재 서버 시간을 넣어주었습니다.
  4. "home"을 리턴해주었으므로, 서블릿 환경 설정 파일의 "/WEB-INF/views/" 경로의 'home.jsp'를 반환합니다. DispatcherServlet은 ViewResolver을 통해 home.jsp 파일을 검색하여 응답받습니다.
  5. ${serverTime} 매개변수에 서버 시간 값이 넘겨졌으므로 브라우저에서 JSP를 통해 응답을 받아 Hello World 및 현재 시간이 출력됩니다.