2009. 10. 27. 11:40

Spring MVC

http://www.javajigi.net/display/OSS/Spring_MVC_2

개론


<Life cycle for new technology>

Spring이라는 새로운 Framework이 진정 개발자의 삶을 좀 더 윤택하게 만들어 줄 수 있을까?
현재 우리의 위치는? Spring long live를 위해 우리가 해야 할 일은?

Table of Contents

Over MVC

Applet

<OBJECT NAME="applet_test" WIDTH=100% HEIGHT=100% ALIGN=TOP classid='clsid:xxxxxxx-xxxx-XXXX-XXX-XXX' 
CODEBASE='http://java.sun.com/products/plugin/autodl/jinstall-1_4_0_02-win.cab#Version=1,4,0,02' style="visibility: visible;" >
<PARAM NAME=PLUGINSPAGE VALUE='JRE/JREInstall.htm'>
<EMBED TYPE='application/x-java-applet;version=1.4'
CODE=AppletContainer.class
ARCHIVE=XXX.jar
ALIGN=TOP WIDTH=100% HEIGHT=100% MAYSCRIPT=TRUE
CACHE_OPTION=PLUGIN
CACHE_ARCHIVE=XXX.jar
CACHE_VERSION=3.2005.0328.1745
SCRIPTABLE=FALSE
PLUGINSPAGE='JRE/JREInstall.htm'
application_property_path=FALSE http://localhost/spring/Client.properties'>
</EMBED>
<NOEMBED> <FONT SIZE=4 COLOR=RED>Netscape 4.0 이상으로 Upgrade 하세요~</FONT> </NOEMBED>
</OBJECT>
  • 장점
    애플릿은 거의 모든 브라우저를 지원하며 풍부한 확장성
  • 단점
    클라이어트 PC에 JRE설치
    보안상의 이유로 사용자의 로컬 파일을 액세스 할 수 없음
    애플릿을 다운로드 한 서버로만 네트워크 통신이 가능한 단점
  • 생명주기
    init(), start(), stop(), destroy()

Servlet

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{
res.setContentType( "text/html");
PrintWriter out = res.getWriter();

String szName = res.getParameter( "name");
out.println( "<HTML>");
out.println( "<HEAD><TITLE>Servelt Test</TITLE></HEAD>");
out.println( "<BODY>Hello, " + szName+ "!!</BODY>");
out.println( "<HTML>");
}
  • 장점
    Thread를 생성하여 서비스를 제공하기 때무에 CGI보다 오베헤드가 적다.
    서블릿간 통신이 가능하다.
  • 단점
    느린실행속도, WAS필요, View 구현이 어려움.
  • 생명주기
    init(), service(), destroy()

Jsp

<HTML>
<HEAD><TITLE>JSP Test</TITLE></HEAD>
<BODY>
<%
String szName = request.getParameter( "name");
%>
Hello, <%= szName%>!!
</BODY>
</HTML>
  • 장점
    Servlet보다 쉽다. 디자인 부분과 로직을 분리.
  • 단점
    객체지향적으로 구현하기 어렵다.
  • 생명주기
    jspInit(), _jspService(), jspDestroy()

Model 1 vs Model2

Model1은 클라이언트가 JSP에 요청을 날리고 응답을 받는 페이지 중심
Model2는 클라이언트의 요청을 servlet이 중재자 또는 컨트롤러로서 동작하고 jsp와 자바빈즈에 요청을 위임한다.

Model1 vs Model2


Building Framework with Design Patterns

  • Extended MVC Architecture







  • Front Controller
    일반화된 Servlet으로 Front에서는 JSP/html을 상대하고 Backend에서는 Business Logic을 상대
    (session처리, page navigation, security, logging 등 일반적인 기능처리)
  • Command Processor

    Front Controller역할을 하는 Control Servlet에서는 Business Logic에 관한 사항을 숨겨져야 한다.
    예를 들어 Servlet에서는 아래와 같은 코드가 존재할 수 있다.
    Command cmd = getCommand( request);
    cmd.execute();


  • Abstract Factory

    사용자의 다양한 비지니스 요청을 파라미터(<input type = "hidden" name="command_name" value="address">)로 받아들여 ControlServlet에서 해당 값을 가지고 CommandProcessor의 객체를 생성하여 사용.
    예를 들어 위의 getCommand()메소드의 내부에는 아래와 같은 코드를 가질 수 있다.
    String szMethodName = ( String) request.getParameter( "command_name");
    return commandFactory.getCommand( szMethodName);


  • Session Facade

    ControlServlet은 오직 TellerCP를 CommandProcessor를 통해서 간접 호출하면, 이 TellerCP가 해당
    Business Object들을 선별적으로 호출하여 일을 처리.
    Business Layer내부에 있는 다양한 object들을 숨기고 대변인 방식.(확장성)
  • Adaptor


  • Interface


  • ORM

  • Final Framework Architecture


    참조 corej2eepattern

Spring MVC

새로운 프레임웤을 마스터하는 것은 새 프레임웤의 APIs 만을 공부하는 것보다 많을 것을 필요로 한다.
자바 API를 따라 프로그램을 만들었다고 무조건 재사용가능한 객체지향적인 프로그램이 만들어 지는 것은 아닌것처럼,
spring API를 이용했다고 해서 DI/AOP 등을 모두 지원하는 프로그램이 만들어 지는 것은 아니다.

Layers of Abstractions

스프링 MVC 어플리케이션은 일련의 레이어들로 분류된다.

  • 일반적인 웹어플리케이션 레이어

  • Spring MVC application layers

Layer Implementation Dependency
User Interface View,ViewResolver Domain model
Web Controller Service layer,Domain model
Service X,(ApplicationContext) Domain model, Persistent
Domain Model X X(Many other layers have dependencies on the domical model.)
Data Access Jdbc., Orm. Service Layer
Layer vs Tier

레이어(Layer)는 아키텍처 패턴의 일종으로 볼 수 있다. 워낙 보편적인 개념이어서 소프트웨어 공학쪽에서 출현한 기원은 모르겠지만,
POSA1에 등장한다.
최근 들어서는 티어와 레이어가 다소 혼용되는 감이 있는데, 티어는 기본적으로 다소 물리적인 배포를 취급하는 측면이 강하고,
레이어는 논리적이고 추상적인 분할이라고 할 수 있다. 다시 말해 레이어는 개념적인 경계영역이고 필요에 의해 물리적으로 독립된 것은 아니다.


Spring MVC 들여다보기


  1. web.xml
    /WEB-INF/web.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' 'http://java.sun.com/dtd/web-app_2_3.dtd'>
    <web-app>
    <servlet>
    <servlet-name>tradingapp</servlet-name>
    <servlet-class>
    org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>tradingapp</servlet-name>
    <url-pattern>*.htm</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <taglib>
    <taglib-uri>/spring</taglib-uri>
    <taglib-location>/WEB-INF/spring.tld</taglib-location>
    </taglib>
    </web-app>

    web.xml에서 DispatcherServlet이 이용할 servletname-servlet.xml의 경로를 특별히 지정할 필요는 없이
    /WEB-INF/의 하위에 동일하게 위치시키면 된다.

  2. DispatcherServlet
    DispatcherServlet은 전형적인 Front Controller패턴이다.
    SpringMVC에서 하나의 요청에 대한 라이프 사이클 및 DispatcherServlet
  3. springapp-servlet.xml
    /WEB-INF/tradingapp-servlet.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    <bean id="urlMapping"
    class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="urlMap">
    <map>
    <entry key="/portfolio.htm">
    <ref bean="portfolioController"/>
    </entry>
    <entry key="/logon.htm">
    <ref bean="logonForm"/>
    </entry>
    <entry key="/trade.htm">
    <ref bean="tradeForm"/>
    </entry>
    </map>
    </property>
    </bean>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
    <property name="prefix"><value>/WEB-INF/jsp/</value></property>
    <property name="suffix"><value>.jsp</value></property>
    </bean>

    <bean id="portfolioController"
    class="com.devx.tradingapp.web.PortfolioController">
    <constructor-arg index="0">
    <ref bean="portfolio"/>
    </constructor-arg>
    </bean>

    <bean id="portfolio" class="com.devx.tradingapp.business.Portfolio">
    <constructor-arg index="0"><value>100000</value></constructor-arg>
    <constructor-arg index="1">
    <map>
    <entry key="IBM"><value>50</value></entry>
    <entry key="SUNW"><value>300</value></entry>
    <entry key="DELL"><value>200</value></entry>
    </map>
    </constructor-arg>
    </bean>

    <bean id="logonValidator" class="com.devx.tradingapp.web.LogonValidator"/>

    <bean id="logonForm" class="com.devx.tradingapp.web.LogonFormController">
    <property name="sessionForm"><value>true</value></property>
    <property name="commandName"><value>credentials</value></property>
    <property name="commandClass"><value>com.devx.tradingapp.business.Credentials</value></property>
    <property name="validator"><ref bean="logonValidator"/></property>
    <property name="formView"><value>logon</value></property>
    <property name="successView"><value>portfolio.htm</value></property>
    </bean>

    <bean id="tradeForm" class="com.devx.tradingapp.web.TradeFormController">
    <constructor-arg index="0">
    <ref bean="portfolio"/>
    </constructor-arg>
    </bean>

    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename"><value>messages</value></property>
    </bean>

    </beans>
  4. URL Mapping
    BeanNameUrlHandlerMapping : s the default - where URLs are matched to bean names
    SimpleUrlHandlerMapping : provides central means of configuring URLs and allows interceptors
    Be Careful

    위 springapp-servlet.xml의 "urlMapping" Bean에서
    <property>가 <map>을 사용할 경우에는 <property>의 name속성의 값을 반드시 "urlMap"으로 지정해야 한다.


  5. Controller
    /WEB-INF/src/com/devx/tradingapp/web/PortfolioController.java
    package com.devx.tradingapp.web;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.Controller;

    public class PortfolioController implements Controller {

    public ModelAndView handleRequest(HttpServletRequest request,
    HttpServletResponse response) {

    return new ModelAndView("/WEB-INF/jsp/portfolio.jsp");
    }
    }

    Controller interface는 handleRequest()라는 단 하나의 메소드만을 정의하고 있다.
    handRequest()를 통해 리턴되는 객체의 타입은 ModelAndView이다.

    Controller종류
    • AbstractCommandController : use for populating a command object with request parameter
    • MultiActionController : allows for many methods in same class
    • SimpleFormController: best to use for processing forms
    • AbstractWizardFormController: use for processing wizards
      • method : onBind(), validatePage(), getTargetPage()
      • parameter : _target,_finish,_cancel,_page
    • AbstractFormController: parent of both Simple, AbstractWizardFormControllers.Requires before/after view names to be configured programmatically
    SimpleFormController를 사용할 경우 필요한 property
    • commandClass?the class of the object that will be used to represent the data in this form.
    • commandName?the name of the command object.
    • sessionForm?if set to false, Spring uses a new bean instance (i.e. command object) per request, otherwise it will use the same bean instance for the duration of the session.
    • validator?a class that implements Spring's Validator interface, used to validate data that is passed in from the form.
    • formView?the JSP for the form, the user is sent here when the controller initially loads the form and when the form has been submitted with invalid data.
    • successView?the JSP that the user is routed to if the form submits with no validation errors.

    redirect vs forward
    • redirect를 사용할 경우 해당 URL이 브라우저에 나타나지만, forward를 사용할 경우 기조의 URL을 유지한다.
    • redirect는 해당 web context 외부의 url을 사용할 수 있지만, forward는 해당 web context내부에서만 사용된다.
    • redirect 방법
      return new ModelAndView( new org.springframework.web.servlet.view.RedirectView( "url"));
      또는
      response.sendRedirect( "url");
      return null;
    • forward 방법
      request.getRequestDispatcher( "url").forward( request, response);
      reutnr null;


  6. ModelAndView
    ModelAndView는 여러개의 생성자를 갖고 있지만 사용하기는 쉽다.
    ModelAndView 객체는 MVC 패턴에서 Model과 View를 나타낸다.
    spring에서 일반적인 모델을 java.util.Map 타입의 객체이나 일반적인 자바빈의 객체가 될 수 있다.
    View의 이름은 ViewResolver에 의해 형성된 로직컬한 이름이다.
  7. View Resolver
    ViewResolver는 Controller가 리턴하는 view에 prefix와 suffix를 추가하는 역할을 한다.
    ViewResolver는 controller와 view 사이의 de-coupling을 제공한다.

다양한 예제들

Spring WEB Flow

SWF에 대해 알아봅시다.

Spring IDE

SPring IDE Installation
Spring IDE Guilde
Spring WebFlwEditor

Framework 비교

comparing web framework

토론꺼리

  • M-V-C 중 가장 중요한 부분은?
  • Spring long live를 위해 우리가 해야 할 일은?

참고문헌

문서에 대하여

최초작성자 : [그이름]
최초작성일 : 2006년 4월 17일
버전 : 0.1


'프로그래밍 > Spring' 카테고리의 다른 글

Spring2.5 애노테이션 기반 설정  (0) 2009.09.25
Spring  (0) 2009.03.25