Transcript Spring_MVC

Chapter 13. Web MVC Framework
이윤걸
이대엽










What is MVC(Model-View-Controller)?
Spring Web MVC의 기능
DispatcherServlet
Controllers
Handler mappings
Views and resolving them
Using locales
Using themes
Spring’s multipart (file upload) support
Using Spring’s form tag library

Model : 비즈니스 영역의 상태정보 표현
View : 비즈니스 영역에 대한 프레젠테이션 뷰
Controller : 입력 및 흐름 제어

개발 방식


◦ 모델 1 : 가장 기본적인 개발방식, JSP에서 전담
◦ 모델 2 : MVC에 근간

모델 1 개발방식
1
요청
4
브라
우저
JSP
응답
2
자바빈
애플리케이션 서버
3
엔터프라이즈 서버/
데이터 소스

모델 2 개발방식
1
요청
5
브라
우저
(컨트롤러)
서블릿
응답
2
3
뷰(JSP)
4
모델
(자바빈)
애플리케이션 서버
엔터프라이즈 서버/
데이터 소스

Spring MVC
HandlerMapping
2
요청
1
3
Controller
DispatcherServlet
ModelAndView
6
4
5
ViewResolver
View







각 MVC role간의 명확한 분리
프레임워크 및 애플리케이션에 대한 강력하고 직
관적인 설정
Adaptability, non-intrusiveness
재사용 가능한 비즈니스 코드 – 중복 제거
Customizable 바인딩, 유효성 검사
Customizable 핸들러 맵핑, 뷰 resolution
유연한 모델 transfer – via name/value support




Customizable 로케일 및 테마 resolution,
Spring 태그 라이브러리, JSTL, Velocity 등
단순하지만 강력한 Spring 태그 라이브러리
JSP 폼 태그 라이브러리(Spring 2.0)
현재 HTTP 요청이나 HTTP Session scope을
lifecycle로 가지는 빈 지원



Spring 역시 다른 웹 MVC 프레임워크와 마찬가지
로 request-driven임
즉, 요청을 컨트롤러로 디스패치하는 서블릿 중심
으로 이루어져 있음
그러나 Spring의 DispatcherServlet은 여기에만
그치지 않고 Spring의 IoC 컨테이너와 기타
Spring이 제공하는 기능들을 완전히 통합할 수 있
도록 해줌

Workflow in Spring Web MVC
요청
요청 위임
Front
Controller
Controller
Model
응답
응답 렌더링 위임
제어
반환
요청 처리
Model
모델 생성
응답 렌더링
View
Template
서블릿 엔진(예, Tomcat)

DispatcherServlet의 상속구조
javax.servlet.http
HttpServlet
org.springframework.web.servlet
HttpServletBean
org.springframework.web.servlet
FrameworkServlet
org.springframework.web.servlet
DispatcherServlet

DispatcherServlet을 등록(web.xml)
◦ DispatcherServlet 초기화시 WEB-INF 디렉터리에서
[servlet-name]-servlet.xml 파일을 탐색
◦ 따라서 여기에서는 /WEB-INF/blog-servlet.xml 파일을
탐색

WebApplicationContext
◦ ApplicationContext를 확장하여 웹 애플리케이션에 필요한 추가
기능을 제공
◦ 기본적으로 DispatcherServlet은 애플리케이션 초기화시
XmlWebApplicationContext에 다음의 bean이 선언되어 있는지
를 검사 (WEB_APPLICATION_CONTEXT_ATTRIBUTE 필드)








HandlerMapping
->
ViewResolver
->
LocaleResolver
->
MultipartResolver
->
ThemeResolver
->
HandlerExceptionResolver
Controllers
->
HandlerInterceptors
->
“handlerMapping”
“viewResolver”
“localeResolver”
“multipartResolver”
“themeResolver”
-> “handlerExceptionResolver”
“??”
“??”

WebApplicationContext의 special beans
빈 타입
설명
Controllers
MVC의 ‘C’를 이루는 컨트롤러들
Handler mappings
전-후처리기 및 컨트롤러 실행목록을 처리(URL 맵핑)
View resolvers
View 이름을 토대로 뷰 처리를 위해 resolving 수행
Locale resolvers
클라이언트가 사용하고 있는 로케일을 resolving, 지역화
Theme resolvers
웹 애플리케이션이 사용하는 테마를 resolving, personalization
Multipart file resolver
HTML 폼으로부터 파일 업로드 처리
Handler exception
resolver(s)
예외 발생시 특정 view나 복잡한 예외처리 코드로 맵핑

기본값은 DispatcherServlet.properties에 정의



컨트롤러는 일반적으로 서비스 인터페이스에 정의된
애플리케이션의 behavior에 대한 접근을 제공
컨트롤러는 사용자 입력을 해석하고 변환하여 view를
통해 그 입력에 대한 결과를 돌려줌
Spring에서는 다음과 같은 유형의 컨트롤러를 제공
◦ Form-specific controllers
◦ Command-based controllers
◦ Wizard-style controllers

org.springframework.web.servlet.mvc.Controller
인터페이스에 기반
public interface Controller {
ModelAndView handleRequest(
HttpServletRequest request,
HttpServletResponse response) throws
Exception;
}














AbstractController
BaseCommandController
WebContentGenerator
ParameterizableViewController
AbstractUrlViewController
UrlFilenameViewController
MultiActionController
AbstractCommandController
AbstractFormController
SimpleFormController
AbstractWizardFormController
CancellableFormController
ServletForwardingController
ServletWrappingController

Spring MVC가 제공하는 컨트롤러 클래스
컨트롤러 유형
클래스
유용한 상황
단순
Controller(인터페이스)
AbstractController
극도로 간단한 컨트롤러를 만들고자 할 때 사용.
기본적인 자바 서블릿이 제공하는 것보다 기능이
약간 더 많음
일회성
ThrowawayController
요청을 명령으로서 처리하는 단순한 방법을 사용
하고자 할 때 사용. WebWork의 Action과 유사
다중 액션
MultiActionController
비슷하거나 관련있는 로직을 수행하는 다수의 액
션을 가지고 있을 때 사용
명령
BaseCommandController
AbstractCommandController
요청으로부터 하나 이상의 파라미터를 받아서 다
른 객체에 바인딩시켜야 할 떄 사용. 또한 파라미
터의 유효성 검증 기능이 포함됨
폼
AbstractFormController
SimpleFormController
입력 폼을 사용자에게 보여주며 입력된 데이터를
처리해야 하는 경우에 사용
AbstractWizardFormController
사용자로 하여금 다수의 페이지에 걸친 복잡한 입
력 폼들을 거치도록 해야 할 경우에 사용(실질적
으로는 하나의 폼으로서 처리됨)
마법사

AbstractController에서 제공하는 기능
기능
설명
supportedMethods
이 컨트롤러가 어떤 메소드를 받아들여야 하는지를 나타냄. 일반적으로 GET과
POST 둘 모두 지정되어 있음. 지정된 메소드가 아니면ServletException이 발생
requiresSession
컨트롤러가 주어진 작업을 처리하기 위하여 HTTP 세션을 필요로 하는지를 나타
냄. 요청을 받을 시 세션이 없을 경우 ServletException이 발생
synchronizeSession
사용자의 HTTP 세션에 대하여 컨트롤러를 동기화하고자 할 때 사용
cacheSeconds
HTTP 응답에 캐싱 지시자(caching directive)를 생성하고자 할 때 사용하며 양
의 정수값으로 지정. 기본값은 -1이며 캐싱 지시자가 생성되지 않음
useExpireHeader
컨트롤러가 생성된 응답에 HTTP 1.0에 compatible한 “Expires” 헤더를 지정할
때 사용. 기본값은 true.
useCacheHeader
컨트롤러가 생성된 응답에 HTTP 1.1에 compatible한 “Cache-Control” 헤더
를 지정할 때 사용. 기본값은 true.

AbstractController를 사용할 경우
hadleRequestInternal()만 구현해주면 됨
컨트롤러 등록
hello.jsp

ParameterizableViewController
◦ AbstractController를 확장
◦ 앞서 살펴보았던 AbstractController와 동일하나
setViewName(String) 메서드를 이용하여 View 이름을
지정해줄 수 있음
◦ 뷰 이름을 Java 클래스 내에 하드코딩할 필요가 없어짐

UrlFilenameViewController
◦ AbstractUrlViewController를 확장
◦ URL을 검사하여 요청 파일의 이름을 알아내어 그 이름을
뷰 이름으로 사용함.
◦ Ex) http://www.springframework.org/index.html의
경우 index가 뷰 이름이 됨.

MultiActionController
◦ 한 컨트롤러 클래스 내에 여러 여러 action이 포함
◦ 한 컨트롤러 내에 비슷한 공통적인 기능이 다수 포함되어 있
으나 각각의 진입점을 가질 필요가 있을 경우 편리하게 사용
◦ MultiActionController의 기능
기능
설명
delegate
MultiActionController의 하위 클래스를 생성하지 않고 위임 객체를 이용하
여 MultiActionController를 이용할 경우 사용함.
methodNameResolver
클라이언트로부터 들어오는 요청에 기반하여 호출해야할 메소드를
resolving하는 전략이 필요한데, 이러한 전략이 MethodNameResolver에 정
의됨

MultiActionController의 메소드 정의
◦ 오버로딩이 허용되지 않음
◦ 다음의 메소드 서명을 따름
public [ModelAndView | Map | void] anyMeaningfulName(
HttpServletRequest, HttpServletResponse
[, Exception | anyObject]);
◦ 따라서 다음의 메소드 서명을 가진 메소드 선언이 가능
public ModelAndView doRequest(HttpServletRequest,
HttpServletResponse)
public ModelAndView doLogin(HttpServletRequest,
HttpServletResponse, Login)
public ModelAndView processException(HttpServletRequest,
HttpServletResponse, IllegalArgumentException)
public void goHome(HttpServletRequest, HttpServletResponse)
public Map doRequest(HttpServletRequest, HttpServletResponse)

MultiActionController의 MethodNameResolver
◦ 들어오는 요청에 근거하여 메소드 이름을 resolving 해줄 책임을 맡고
있음
◦ Spring에서는 다음의 MethodNameResolver 구현체를 제공
 ParameterMethodNameResolver
 요청 파라미터를 메소드명으로 사용
 /index.view?testParam=testIt
-> testIt(request, response)
 InternalPathMethodNameResolver
 요청경로의 파일명을 메소드명으로 사용
 /testing.view -> testing(request, response)
 PropertiesMethodNameResolver
 사용자가 정의한 properties 객체로 요청 URL을 메소드명에 맵핑
 /index/welcome.html -> /**/welcom?.html이란 것이 정의되어 있으
면 그것과 맵핑된 메소드가 실행.

MultiActionController 예제
◦ ParameterMethodNameResolver

Command controllers
◦ 데이터 객체와 HttpServletRequest 객체간의 바인딩 지원
◦ 스트러츠의 ActionForm과 유사하다고 하나 데이터 객체가
Framework-specific 인터페이스를 구현할 필요가 없음
◦ 유형




AbstractCommandController
AbstractFormController
SimpleFormController
AbstractWizardFormController

AbstractCommandController
◦ 요청 파라미터를 데이터 객체와 바인딩할 수 있음
◦ command object에 대한 유효성 검증(validation)기능 제공

AbstractFormController
◦ 폼 전송을 지원하는 컨트롤러
◦ 사용자가 폼을 채우면 AbstractFormController가 필드를
바인딩 하며 command object에 대한 유효성 검증을 수행
한 다음 컨트롤러로 리턴된 객체를 이용하여 적절한 행위를
수행
◦ 개발자는 폼을 나타내는 뷰와 submission 성공시 보여줄 뷰
를 결정하는 메소드를 구현해야 함

SimpleFormController
 입력폼을 구현하기 위하여 제공되는 컨트롤러
 하나의 컨트롤러로 입력이나 수정에 대한 작업을 처리 가능
 GET 방식과 POST 방식에 대한 처리 과정이 서로 상이하기 때문
 Spring 프레임워크 워크북 p.335~347

AbstractWizardFormController
◦ 마법사 기능을 가진 폼을 구현할 때 사용
◦ 개발자는 validatePage(), processFinish() 및
processCancel() 메소드를 구현해야 함
◦ setPage() 메소드를 이용하여 페이지에 마법사 페이지들
을 구성하는 페이지에 대한 String 배열을 전달
◦ setCommandName()과 setCommandClass() 메소드를
이용하여 command 객체를 지정
◦ 이 밖에도 필요에 따라 개발자는 referenceData(),
getTargetPage(), onBindAndValidate(),
setAllowDirtyBack(), setAllowDirtyForward() 등의 메
소드를 재정의할 수 있음
◦ 스프링 인 액션. p.294~300

클라이언트 요청에 대한 적절한 핸들러와 맵핑 처리
public interface HandlerMapping {
String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE;
public HandlerExecutionChain getHandler(
HttpServletRequest request) throws Exception;
}

HandlerExecutionChain
◦ 요청-핸들러 맵핑 정보, 요청-핸들러 interceptor 목록

유형
◦ SimpleUrlHandlerMapping
◦ BeanNameUrlHandlerMapping - 기본값

앞의 두 HandlerMapping 클래스 모두
AbstractHandlerMapping을 확장하며 다음의 프
로퍼티를 가짐
interceptors : 사용할 인터셉터 목록
defaultHandler : 사용할 기본 핸들러
order : order 프로퍼티 값 (Ordered 인터페이스)
alwaysUseFullPath : true일 경우 적절한 핸들러를 찾을
때 현재 서블릿 컨텍스트내의 완전한 경로를 이용. false이
면 현재 경로만 이용.
◦ urlPathHelper : URL을 검사시 UrlPathHelper 사용
◦ urlDecode : 기본값은 false이며, URI decode 여부 결정
◦ lazyInitHandlers : 기본값 false. 싱글턴 핸들러에 대한
lazy initialization 허용 여부
◦
◦
◦
◦

BeanNameUrlHandlerMapping
◦ 기본값으로 지정되어 있는 HandlerMapping 클래스
◦ 빈 이름과 URL을 맵핑
◦ ANT-Style의 맵핑 가능
◦ BeanNameUrlHandlerMapping이 단순하긴 하지만
presentation 계층 URL과 컨트롤러 이름간의 결합을 발생시
키므로 권장하지 않음
 스프링 인 액션, p.281

SimpleUrlHandlerMapping
◦ URL 패턴을 직접적으로 컨트롤러에 맵핑
◦ 컨트롤러 빈을 정의하고 맵핑을 별도로 설정하는 불편함
이 있기는 하지만 맵핑 정보를 수정할 필요가 있을 시
BeanNameUrlHandlerMapping에 비해 효율적으로 관
리 가능

Intercepting request - HandlerInterceptor
◦ 실제로 핸들러가 실행되기 전(before)과 요청에 대한 처
리가 완전히 완료되었을 때(after)의 필요한 작업을 수행
◦ preHandle() 및 postHandle() 메소드를 사용
◦ preHandle() 메소드는 리턴값으로 boolean값을 리턴하며,
true일 경우, 계속 요청 처리를 수행하고, false일 경우 요
청 처리를 중단
◦ 예제
 http://whiteship.tistory.com/841 ^^;

Intercepting request - HandlerInterceptor

레퍼런스에 오타 발견!!!! ㅋㅋ (p.265)
요렇게 고쳐야 합니다.

ModelAndView 객체에 부여된 논리적인 뷰 이름
으로 사용자에게 결과를 렌더링할 View 빈을 결정
public interface ViewResolver {
public View resolveViewName(
String viewName, Locale locale) throws Exception;
}

ViewResolve 구현체
◦
◦
◦
◦
◦
◦
AbstractCachingViewResolver
XmlViewResolver
ResourceBundlerViewResolver
UrlBasedViewResolver
InternalResourceViewResolver
VelocityViewResolver, FreeMarkerViewResolver

View Resolvers
ViewResolver
Description
AbstractCachingViewResolver
뷰에 대한 캐싱 지원
XmlViewResolver
XML 설정파일을 통한 뷰 설정 지원
기본 설정 파일 : /WEB-INF/views.xml
ResourceBundleViewResolver
ResourceBundle에 포함되어 있는 빈 정의를 사용하는
뷰에 대한 구현. 기본값은 views.properties
UrlBasedViewResolver
명시적인 맵핑 정의없이 뷰 이름을 직접적인 URL로 지정
UrlBasedViewResolver의 하위클래스로서
InternalResourceViewResolver InternalResourceView와 JstlView, TilesView의 하위클
래스를 지원
VelocityViewResolver /
FreeMarkerViewResolver
UrlBasedViewResolver의 하위클래스로서,
VelocityView나 FreeMarkerView를 지원

ViewResolver 설정 예제

Chaining ViewResolvers
◦ Spring은 하나 이상의 view resolver를 사용할 수 있도록
해줌
◦ 특정 상황에 특정한 뷰를 재정의 가능
◦ 설정 예

Redirecting to views
◦ InternalResourceViewResolver/InternalResourceView에
의해 처리되는 내부적으로 RequestDispatcher.forward()나
RequestDispatcher.include() 메소드에 의해 처리됨
◦ view가 렌더링되기 전 클라이언트에 HTTP redirect를 발생
시키고자 할 경우가 있음
◦ redirect 유형
 RedirectView
 redirect: prefix
 forward: prefix

RedirectView
◦ 스프링에서 제공하는 RedirectView 클래스의 인스턴스를 생
성하여 리턴.
◦ 이 경우 DispatcherServlet은 일반적인 view resolution 메
커니즘을 사용하지 않고 주어진 redirect 뷰를 사용
◦ 내부적으로 HttpServletResponse.sendRedirect()를 호출

redirect: prefix
◦ RedirectView가 컨트롤러와 강결합. 컨트롤러는 response
가 어떻게 처리되었는지를 알 필요가 없음
◦ redirect: prefix를 사용할 경우 컨트롤러는 redirection이
일어났는지 알지 못함

forward: prefix
◦ forward prefix를 사용하는 view는 UrlBasedViewResolver
와 하위클래스에 의해 resolving됨
◦ 내부적으로 RequestDispatcher.forward()를 사용
◦ redirect: prefix와 마찬가지로 컨트롤러와 약결합




요청이 들어오면 DispatcherServlet는 locale
resolver를 탐색하고 적절한 locale 적용을 시도
RequestContext.getLocale() 메소드를 이용하여
locale resolver에 의해 resolving된 locale을 얻을
수 있음
특정 상황에서 locale을 변경하기 위하여(요청 파라미
터에 의해) HandlerInterceptor 인터페이스의 구현체
를 이용하여 interceptor를 첨부할 수도 있음
Locale Resolvers
◦ AcceptHeaderLocaleResolver
◦ CookieLocaleResolver
◦ SessionLocaleResolver

LocaleChangeInterceptor




org.springframework.ui.context.ThemeSource를
이용하여 테마 기능을 웹 애플리케이션에 적용가능
WebApplicationContext 인터페이스에서
ThemeSource 인터페이스를 확장하긴 하나 책임은
모두 구현체에 위임
기본적으로 ResourceBundleThemeSource가
properties 파일을 읽어 테마를 적용
Theme resolvers
◦ FixedThemeResolver
◦ SessionThemeResolver
◦ CookieThemeResolver


org.springframework.web.multipart
MultipartResolver의 구현체
◦ CommonsMultipartResolver
◦ CosMultipartResolver


기본적으로 Spring에서는 multipart 처리를 하지
않음
Web application context에 multipart resolver
를 등록한 다음부터는 request에 multipart가 있
는지를 검사하여, 만약 multipart가 발견되면 지정
한 MultipartResolver가 요청을 처리

Using the MultipartResolver

commons-fileupload.jar나 cos.jar 필요

Handling a file upload in a form

Handling a file upload in a form

Handling a file upload in a form
*uploadFormFile() 메소드는 Spring 프레임워크 워크북 참조


Spring 2.0 부터 제공
설정: spring-form.tld, taglib 지시자에 선언

form 태그

input 태그
◦ text type의 input 태그로 렌더링

checkbox 태그
◦ Spring 레퍼런스 p.277의 Preferences class

radiobutton 태그

password 태그
◦ showPassword : 기본값은 패스워드가 보이지 않음

select 태그

option 태그

options 태그

textarea 태그

hidden 태그

errors 태그

errors 태그




Spring Framework Rerefence, Interface21
Spring 프레임워크 워크북, 박재성, 한빛 미디어
스프링 인 액션, 크렉 월즈/이태상 옮김, 에이콘
백기선님 블로그, http://whiteship.tistory.com/
부족한 예제, 불충분한
설명을 그저 양으로 때
운 발표였습니다. 경청
해 주셔서 감사합니다.
^^;