Spring MVC Basic

From JCFWiKi

Jump to: navigation, search

그림:check.gif

  • 산출물: Spring MVC 개요
  • 작성자: 나윤주
  • 최초작성일 : 2008/06/23
  • 최종작성일 : 2008/06/27

Copyright © 2008 Daewoo Information Systems Co., Ltd.

그림:information.gif

  • 이 문서는 Spring Framework에서 제공되는 Web MVC Framework인 Spring MVC에 관한 것입니다.

목차

[편집] Spring MVC 소개

  • Web MVC framework은 Spring Reference의 Chapter 13. Web MVC framework에서 언급한 대로 다음과 같은 설계사상을 가지고 있다.
    • 'Spring's Web MVC framework is designed around a DispatcherServlet that dispatches requests to handlers, with configurable handler mappings, view resolution, locale and theme resolution as well as support for upload files.' (원문: http://static.springframework.org/spring/docs/2.5.x/reference/mvc.html). Web MVC framework는 Request를 Handler에 전달하는 역할을 담당하는 DispatcherServlet과 연동하는 구성요소로 설계된다.
    • 그 요소는 설정이 가능한 handler mapping, view resolution, locale and theme resolution 그리고 파일업로드를 지원하는 요소로 구성된다.
    • 설계의 핵심사상은 최소의 설정으로 패턴화된 다양한 Mapper, Handler 그리고 View를 제공하는 것으로서 간단한 설정을 통해 다양한 Request를 mapping하는 Mapper와 mapping된 Request를 처리하는 Handler, 그리고 비즈니스 모듈을 통해 처리된 컨텐츠를 다양한 View로 처리할 수 있는 기반을 제공한다.
  • 다음 그림은 SpringMVC의 설계사상을 기반으로 구성된 대상 클래스의 Lifecycle과 처리흐름을 나타낸다.
Spring web MVC Framework의 Lifecycle과 workflow
Spring web MVC Framework의 Lifecycle과 workflow
  • Spring web MVC Framework는 기존에 사용되는 Struts, Servlet 등과 같이 웹 어플리케이션의 Presentation Tier에 적용된다. Spring web MVC Framework는 웹 어플리케이션 개발에서 구현과 설정을 간결하고 유연성있게 해준다.
  • Struts와 비교해 보았을때, Struts의 Action 맵핑 대신 CommandController, FormController, MultiActionController 등 상황에 맞는 Controller를 사용할 수 있다. 또한, Java 5+ 이상에서는 annotation을 사용할 수 있어, 설정을 최소화 할 수 있게 해준다.
Controller종류
    * AbstractCommandController : Request 파라미터를 가진 commond 객체를 활용할 경우에 사용한다.
    * MultiActionController : 동일 클래스에서 다양한 이름의 메소드를 정의하고 맵핑하는 경우에 사용한다.
    * SimpleFormController: 정의된 다중 form을 처리할 때 사용한다.
    * AbstractWizardFormController: wizard를 처리할 때 사용한다.
          o method : onBind(), validatePage(), getTargetPage()
          o parameter : _target,_finish,_cancel,_page
    * AbstractFormController: Simple과 AbstractWizardFormController의 부모 클래스로, 사용하기 위해서 프로그래밍을 통해 before/after view 이름이 설정되어야 한다.

[편집] Spring MVC의 동작

Spring web MVC Framework의 workflow
Spring web MVC Framework의 workflow
  • Spring web MVC Framework는 크게 Dispatcher Servlet, Controller, View Template로 구성되어 있다. (Spring Reference 참고)

[편집] Dispatcher Servlet

  • Spring web MVC Framework의 Dispatcher Servlet은 다른 web MVC Framework와 마찬가지로 사용자의 요청을 url에 따라 정의된 Controller에 전달하고 요청에 따른 결과를 사용자에게 보여주는 역할을 한다.
  • Dispatcher servlet은 org.springframework.web.servlet.DispatcherServle에 의해 표현되며, 클라이언트 요청을 처리하기 위한 Front Controller Design Pattern이다.
  • 클라이언트에서 요청한 모든 URL에 대하여 이 서블릿은 클라이언트의 Request가 Controller에 가기전에 해당 Request를 가로챈다.
  • Web Configuration File은 Dispatcher Servlet이 클라이언트의 Request에 대하여 invoked 되도록 정의되어 있다.
  • Web Configuration File인 web.xml에서 서블릿 맵핑을 시켜줌으로써 사용할 수 있다.
    • 아래의 코드와 같이 설정할 경우, <servlet-name>과 맵핑되는 blog-servlet.xml 파일이 요청되며, *.do의 url 요청은 모두 DispatcherServlet을 거치게 된다.
<servlet>
	<servlet-name>blog</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>blog</servlet-name>
	<url-pattern>*.do</url-pattern>
</servlet-mapping>
  • blog-servlet.xml은 빈으로 등록하는 url과 맵핑되는 Controller를 지정해주는 역할을 하게 된다.
    • 예제코드에서 보는 것과 같이 /createBlog.do라는 url로 접근을 하면, blog.web.CreateBlogController 클래스의 메소드가 실행된다.
    • 지정된 Controller 클래스는 Controller 인터페이스 또는 특정 Controller 클래스를 상속된다.
<?xml version="1.0" encoding="UTF-8"?>
 
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:p="http://www.springframework.org/schema/p" 
		xmlns:context="http://www.springframework.org/schema/context"
		xsi:schemaLocation="http://www.springframework.org/schema/beans 
			http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/context
			http://www.springframework.org/schema/context/spring-context-2.5.xsd">
 
	<!-- the application context definition for the blog DispatcherServlet -->
	<bean name="/createBlog.do" class="blog.web.CreateBlogController"/>
	<bean name="/findBlogs.do" class="blog.web.FindBlogsController"/>
	
</beans>

[편집] 다중 DispatcherServlet 적용하기

  • 클라이언트의 Request에 대한 다양한 servlet-mapping을 제공하기 위해 다중 DispatcherServlet 클래스를 등록하고 매핑정보를 web.xml에 설정한다.
  • 예를 들어, JstlView(JSP에서 JSTL을 활용하는 경우)와 JsonView(Ext-js에서 JSON을 활용하는 경우)를 동시에 하나의 웹 어플리케이션에서 활용하는 경우, 다음과 같이 설정하여 적용할 수 있다.
<servlet>
	<servlet-name>blog</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet>
	<servlet-name>blog2</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>blog</servlet-name>
	<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
	<servlet-name>blog2</servlet-name>
	<url-pattern>*.json</url-pattern>
</servlet-mapping>

[편집] Controller

  • web MVC 모델에서, Controller는 전달받은 사용자의 요청을 서비스로 연결해주는 역할을 한다. 또한, 서비스로부터 받은 요청 결과를 다시 사용자에게 전달해 준다. Spring web MVC Framework의 최상위 Controller는 interface로 제공되고, 각 역할에 따라 Form에 관련된 Controller, command에 관련된 Controller 클래스 등을 제공한다. Controller interface는 ModelAndView 타입의 반환 값을 가지는 handleRequest method를 포함하며, 이 메소드에서 사용자에게 전달할 응답 결과를 ModelAndMap 형태로 하여 반환한다.
  • Web controller를 사용하기 위해서는 xxx-servlet.xml 파일에 controller 등록이 필요하다.

  • Controller interface의 사용
    • handleRequest 메소드를 override하여, 이 FindBlogController가 해야하는 동작을 정의한다.
    • 아래의 코드는 findBlogs.do라는 url 요청이 들어오면 blog.web.FindBlogController 클래스의 handleRequest가 수행된다.
<!-- blog-servlet.xml -->
<bean name="/findBlogs.do" class="blog.web.FindBlogController">
	<property name="blogService" ref="blogService"/>
</bean>
/* FindBlogController.java */
/* package 정의 및 import */
public class FindBlogController implements Controller {
	private BlogService blogService;             // 서비스 클래스 정의
 
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
 
		Collection<Blog> blogList = blogService.findBlogs();
		return new ModelAndView("findBlogs", "blogList", blogList);
	}
 
	public void setBlogService(BlogService blogService) {
		this.blogService = blogService;
	}
}
  • SimpleFormController class의 사용
    • 화면의 form 태그와 관련된 동작을 수행할 때 사용한다.
    • formBackingObject 메소드는 form 화면을 보여주기 위한 값 설정에, onSubmit 메소드는 화면의 form 결과를 전달하기 위해 사용한다.
<!-- createBlog.jsp -->
 
<form:form name="blogForm" commandName="create">
	<!-- 중간 생략 -->
</form:form>
<!-- blog-servlet.xml -->
 
<bean name="/createBlog.do" class="blog.web.CreateBlogFormController">
	<property name="blogService" ref="blogService"/>
	<property name="commandClass" value="blog.model.Blog"/>
	<property name="commandName" value="create"/>
</bean>
/* CreateBlogFormController.java */
/* package 정의 및 import */
public class CreateBlogFormController extends SimpleFormController {
	private BlogService blogService;             // 서비스 클래스 정의
	
	protected ModelAndView onSubmit(Object command) throws Exception {
		Blog blog = (Blog) command;
		blogService.createBlog(blog);
		return new ModelAndView(new RedirectView("findBlogs.do"));
	}
	
	protected Object formBackingObject(HttpServletRequest request)
			throws Exception {
		Blog blog = new  Blog();
		blog.setRegDate(new Date());
		return blog;
	}
 
	public void setBlogService(BlogService blogService) {
		this.blogService = blogService;
	}
}
  • MultiActionController class의 사용
    • 하나의 controller 클래스에서 다양한 요청을 처리하기 위해 사용한다.
    • 다음과 같은 형태로 메소드를 작성 해야한다.
public [ModelAndView | Map | void] anyMeaningfulName(HttpServletRequest, HttpServletResponse [, Exception | AnyObject]);
    • 메소드 이름은 맵핑하고자 하는 url 이름과 같게하여 작성한다.
    • 아래의 예제는 위의 FindBlogController 클래스를 변형하여 findBlogs와 deleteBlog를 수행할 수 있게 하였다.
<!-- blog-servlet.xml -->
<bean name="/findBlogs.do" class="blog.web.FindBlogController">
	<property name="blogService" ref="blogService"/>
</bean>
<bean name="/deleteBlog.do" class="blog.web.FindBlogController">
	<property name="blogService" ref="blogService"/>
</bean>
/* FindBlogController.java */
/* package 정의 및 import */
public class FindBlogController extends MultiActionController {	
	private BlogService blogService;             // 서비스 클래스 정의
 
	public ModelAndView findBlogs(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		Collection<Blog> blogList = blogService.findBlogs();
		return new ModelAndView("findBlogs", "blogList", blogList);
	}
	
	public ModelAndView deleteBlog(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		blogService.deleteBlog(Integer.parseInt((String)request.getParameter("blogId")));
		return new ModelAndView(new RedirectView("findBlogs.do"));
	}
 
	public void setBlogService(BlogService blogService) {
		this.blogService = blogService;
	}
}

[편집] View Template

  • 사용자의 요청을 Controller에 전달하고, 또 Controller에서 전달받은 응답 결과를 화면에 보여주기 위해, spring form 태그와 jstl 태그 등을 사용하여 View 페이지를 작성 할 수 있다.

[편집] Spring MVC의 예외처리

  • Spring MVC에서 제공하는 예외처리는 발생하는 예외에 따라 적절한 에러 페이지를 보여주고 싶을 때 사용할 수 있다.
    • springframework의 샘플 코드 중 아래의 petclinic 예제에서는 DataAccessException 또는 TransactionException가 발생할 경우 dataAccessFailure.jsp 페이지로 예외를 넘겨준다.
  • HandlerExceptionResolvers interface를 구현하여 사용자 예외를 직접 처리 할 수 있고, SimpleMappingExceptionResolver class를 사용하여 이미 정의된 예외에 대한 처리를 할 수 있다.
<!-- petclinic-servlet.xml of springframework petclinc sample code -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
	<property name="exceptionMappings">
		<props>
			<prop key="org.springframework.dao.DataAccessException">dataAccessFailure</prop>
			<prop key="org.springframework.transaction.TransactionException">dataAccessFailure</prop>
		</props>
	</property>
</bean>

[편집] Spring MVC Blog 예제 다운로드

  • SpringMVC + springframework + Hibernate3으로 이루어진 예제이다.
  • Spring MVC Blog 예제 다운로드
  • 데이터베이스는 hsql을 사용하였다. 예제를 실행시키기 전에 data 폴더안의 server.bat 파일을 먼저 실행시켜 데이터베이스를 띄워야한다.

그림:information.gif

  • 예제 실행을 위해서는 JDK, 이클립스, 톰캣 등의 개발환경이 필요하다. (개인 개발환경 참고)

[편집] 참고자료