p. MVC Framework(미완) - kimxavi/spring_tutorial GitHub Wiki
스프링 웹 MVC 프레임워크 model-view-controller 아키텍쳐를 제공하고 유연하고 느슨하게 연결된 웹 어플리케이션을 개발할 수 있는 컴퍼넌트들을 준비해준다. MVC 패턴은 어플리케이션의 다양한 측면(입력 로직, 비즈니스 로직, UI 로직)을 분리하도록 초래한다.
- Model : 어플리케이션을 캡슐화 한다. 일반적으로 POJO로 구성할 것이다.
- View : 모델을 렌더링할 책임이 있다. 일반적으로 브라우저에서 해석할 수 있는 HTML 출력을 만든다.
- Controller : 유저의 요청을 처리하고 적합한 모델을 만들고 뷰에 렌더링을 하도록 전달한다.
스프링 웹 MVC 프레임워크는 모든 HTTP 요청과 응답을 다루는 DispatcherServlet 으로 디자인된다. 아래 그림 참조.
DispatcherServlet을 수신하는 HTTP 요청에 대응하는 이벤트의 순서는 다음과 같다.
- HTTP 요청을 받은 후, DispatcherServlet는 적합한 Controller에 요청을 보내기 위해서 HandlerMapping를 찾는다.
- Controller는 요청을 받고 GET/POST 메소드가 사용되어있는 적절한 서비스 메소드를 호출한다. 서비스 메소드는 정의된 비즈니스 로직을 기반으로 모델 데이터를 세팅한고 뷰 이름을 DispatcherServlet에 반환한다.
- DispatcherServlet는 ViewResolver로 부터 요청에 정의된 뷰를 가져오도록 돕는다.
- 뷰가 완료되면, DispatcherServlet은 마지막으로 브라우저에서 렌더링되는 뷰로 모델 데이터를 전달합니다.
위에 언급된 모든 컴퍼넌트(HandlerMapping, Controller, ViewResolver)들은 웹어플리케이션에 필요한 몇가지 추가 기능과 ApplicationContext가 확장된 WebApplicationContext의 한 부분이다.
web.xml 파일에서 URL 매핑을 사용해서 DispatcherServlet가 처리할 요청을 정해준다. 예시를 보자. HelloWeb DispatcherServlet
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring MVC Application</display-name>
<servlet>
<servlet-name>HelloWeb</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloWeb</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
</web-app>
web.xml 파일은 웹 어플리케이션의 WebContent/WEB-INF 디렉토리에 가질 것이다. HelloWeb DispatcherServlet의 초기화가 완료되면 프레임워크는 웹 어플리케이션의 WebContent/WEB-INF 디렉토리에서 [servlet-name]-servlet.xml]의 이름을 가진 파일로 부터 어플리케이션 context를 불러오는 것을 시도할 것이다. 다음에, servlet-mapping 태그는 DispatcherServlet에 의해서 무슨 URL이 다뤄질 것인지 명시한다. 위의 예제에선 .jsp로 끝나는 모든 HTTP 요청은 HelloWeb DispatcherServlet에 의해 처리됩니다. 만약 [servlet-name]-servlet.xml 처럼 기본 파일 이름을 정하기 싫고 WebContent/WEB-INF를 기본 위치로 하기 싫으면, 파일 이름과 위치를 서블릿 리스너 ContextLoaderListener를 web.xml에 넣음으로써 임의로 정할 수 있다. 예제:
<web-app...>
<!-------- DispatcherServlet definition goes here----->
....
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/HelloWeb-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
웹 애플리케이션의 WebContent / WEB-INF 디렉토리에 HelloWeb-servlet.xml 파일에 필요한 구성을 확인하자
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.tutorialspoint" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
아래는 HelloWeb-servlet.xml 파일의 중요한 점이다.
- [servlet-name]-servlet.xml 파일은 전역 범위에서 같은 이름을 가지고 정의 된 bean의 정의를 override하는 bean 정의를 만드는 데 사용됩니다.
- context:component-scan... 태그는 스프링 MVC 어노테이션(@Controller ,@RequestMapping 등등)을 스캐닝하는 능력을 활성화하도록 한다.
- InternalResourceViewResolver는 view의 이름을 해결할 view의 규칙일 것이다. 위의 정의 된 규칙에 따라, 논리적 view라는 hello는 /WEB-INF/jsp/hello.jsp에 위치한 view 구현에 위임된다.
DispatcherServlet은 요청을 컨트롤러에 위임하고 특정 기능을 실행한다. @Controller 어노테이션은 특정 클래스가 컨트롤러의 역할을 하는 것을 나타냅니다. @RequestMapping 어노테이션은 전체 클래스 또는 특정 핸들러 메소드 하나에 URL을 매핑하는 데 사용된다.
@Controller
@RequestMapping("/hello")
public class HelloController{
@RequestMapping(method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}
@Controller는 스프링 MVC 컨트롤러 역할을 하는 클래스를 정의한다. 첫 번째 쓰인 @RequestMapping는 이 컨트롤러의 모든 처리 메소드는 /hello 경로에 상대적이라는 것을 명시한다. 다음 어노테이션 @RequestMapping(method = RequestMethod.GET)는 HTTP GET 요청을 다루는 콘트롤러의 기본 서비스 메소드로 printHello() 메소드를 선언하는데 사용된다. 같은 URL에 POST 요청을 처리하는 다른 메소드를 정의할 수 있다. 아래와 같이 다르게 표현할 수도 있다.
@Controller
public class HelloController{
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}
value 어트리뷰트는 핸들러 메소드가 매핑되어지는 URL을 표시한다. method 어트리뷰트는 HTTP GET 요청을 처리하는 서비스 메소드를 정의한다.
- 서비스 메소드 내부에 요구되는 비즈니스 로직을 정의할 것이다. 요구 사항에 따라 이 메소드 안에 다른 메소드를 호출 할 수 있습니다.
- 정의 된 비즈니스 로직을 바탕으로,이 메소드 내에서 모델을 만들 것입니다. 다른 모델 어트리뷰트를 설정하고 이러한 어트리뷰트들의 결과물은 뷰에 표현하기 위해 의해서 액세스 될 것이다. 이 예시에서는 model.addAttribute("message", "Hello Spring MVC Framework!"); 이 부분이다.
- 정의된 서비스 메소드는 모델을 렌더링하는데 사용될 뷰의 이름을 스트링으로 리턴한다. 이 예는 "hello" 논리적인 뷰의 이름으로 반환된다.
스프링 MVC는 다른 프레젠테이션 기술의 많은 타입의 뷰들을 지원한다. JSPs, HTML, PDF, Excel worksheets, XML, Velocity templates, XSLT, JSON, Atom, RSS feeds, JasperReports 등등이 있다. 그러나, 가장 흔하게 사용되는 것은 JSTL과 함께 작성된 JSP 템플릿 이다. /WEB-INF/hello/hello.jsp를 작성해보자.
<html>
<head>
<title>Hello Spring MVC</title>
</head>
<body>
<h2>${message}</h2>
</body>
</html>
여기서 ${message} 는 Controller 내부에서 설정한 어트리뷰트이다. 많은 어트리뷰트를 설정할 수 있고 이 것들을 뷰에 표현할 수 있다.