개발/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";
}
}
- @Controller 어노테이션으로 컨트롤러임을 명시해 주었습니다. 서블릿 환경설정 파일의 <annotation-driven> 태그가 이를 인식하여 클래스를 컨트롤러로 등록합니다.
- HandlerMapping에 의해 결정된 컨트롤러에서 HandlerAdapter에 의해 실행 메소드가 결정되며, @RequestMapping 어노테이션을 통해 실행 메소드 정보를 제공받습니다. value 값에 해당하는 URL이 GET 방식으로 요청이 들어오면 해당 메소드를 실행합니다.
- model의 addAttribute 메소드를 통해 'serverTime'이라는 이름의 매개 변수에 현재 서버 시간을 넣어주었습니다.
- "home"을 리턴해주었으므로, 서블릿 환경 설정 파일의 "/WEB-INF/views/" 경로의 'home.jsp'를 반환합니다. DispatcherServlet은 ViewResolver을 통해 home.jsp 파일을 검색하여 응답받습니다.
- ${serverTime} 매개변수에 서버 시간 값이 넘겨졌으므로 브라우저에서 JSP를 통해 응답을 받아 Hello World 및 현재 시간이 출력됩니다.