스트럿츠2 아키텍쳐
5. 스트럿츠2 아키텍쳐
struts2 프레임워크는 모든 요청을 필터인 FilterDispacher가 처리하게 된다. FilterDispatcher는 요청이 들어오면
ActionProxy 인스턴스가 생성하고 액션 실행을 위임한다.
ActionProxy는 인터셉터와 리절트 등 액션 실행 구성을 읽어서 ActionInvocation을 초기화하고 실행한다.
ActionInvocation은 실질적인 인터셉터와 액션 리절트의 실행을 담당한다.
- 스트럿츠2 필터 디스패처
필터 기반으로 액션 요청을 처리하는 스트럿츠2 프레임워크는 어떠한 처리를 할 것인지가 web.xml에 의해 결정.
- 설정 관리자/ 액션 매퍼
사용자의 요청이 들어올 때, 어떠한 액션이 URL로 매핑될 것인지에 대해 결정하기 위해 설정 관리자와
액션 매퍼를 사용한다.
설정 관리자(Configuration Manager)는 struts.xml 파일을 사용하여 초기화된다.
필터 디스패처는 액션 요청 처리를 위해 액션 매퍼의 도움을 받아서 보내진 요청이 스트럿츠2 액션을 위한
요청인지의 여부를 판다.
액션 매퍼(Action Mapper)를 통해 액션 요청으로 판단되면 액션 프록시(ActionProxy)에게 제어를 위임한다.
요청된 이름과 일치되는 액션이 발견되지 않으면 오류를 반환한다.
- Action Proxy/ Action Invocation/ Action Context
액션 프록시는 액션 실행을 위해 제공되는 대행자이다. 액션 프록시는 액션 프록시 팩토리 인스턴스를
사용하여 필터 디스패처에 의해 생성되고, struts.xml 파일을 사용하여 초기화되는 설정 관리자를 참조한다.
액션 프록시는 액션 인보케이션을 생성하고, 액션 인보케이션은 액션 실행에 앞서 인터셉터를 찾아서 호출.
액션 프록시는 액션 인보케이션의 invoke() 메소드를 호출한다.
액션 인보케이션은 인터셉터 스택 중 실행할 다음 인터셉터가 있다면, 그 인터셉터의 intercept() 메소드를 호출.
인터셉터의 intercept() 메소드는 파리미터로 넘어온 액션 인보케이션의 invoke() 메소드를 다시 호출하여 체인을
형성한다. 액션 인보케이션이 더 이상 호출할 인터셉터가 없으면 액션을 실행한 다음 리절트를 실행한다.
5.1. 인터셉터란?
인터셉터는 스트럿츠 프레임워크 내부의 소스 코드를 수정하지 않으면서도, 공통 관심 기능이 수행되어
프레임워크에 적용되도록 한다.
인터셉터는 액션과 서로 느슨하게 연결하기 때문에 인터셉터와 액션의 기능이 서로 간편하게 통합될 수 있다.
인터셉터는 특정 액션이 수행되는 것을 가로채서 액션이 수행되기 이전이나 이후에 특정 행동들을 수행한다.
5.1.1. <package> - <interceptors />
- 인터셉터를 위한 요소. <package>를 시작할 때는 그 package에 소속된 action들이 사용할 interceptor를
먼저 정의하는데, 이를 <interceptors>안에 기술한다.
예)
<package>
<interceptors>
<interceptor> - 인터셉터 스택에서 참조할 인터셉터를 등록하는 요소
<interceptor-stack> - <interceptor-ref> 요소를 이용하여 이미 정의된 인터셉터들을 여러 개씩
묶어서 하나의 이름으로 참조할 수 있도록 하는 인터셉터 스택을 정의하는 요소.
<interceptor-ref> - 액션 실행 전/후로 실행될 인터셉터를 지정할 때 사용
</interceptors>
</package>
5.1.2. <package> - <interceptors> - <interceptor>
- 인터셉터를 등록하는 요소. name과 class 속성이 필요.
5.1.3. <interceptor-ref> 와 <interceptor-stack>
- <interceptor-ref> 요소는 액션의 실행 전/후로 실행될 인터셉터를 지정할 때 사용한다.
<interceptor-stack>요소는 <interceptor-ref>요소를 이용하여 이미 정의된 인터셉터들을 여러 개씩 묶어서
하나의 이름으로 참조할 수 있도록하는 인터셉터 스택을 정의하는 요소.
예)
<interceptor-stack name=”basicStack”>
<interceptor-ref name=”exception” />
<interceptor-ref name=”servletConfig” />
<interceptor-ref name=”prepare” />
<interceptor-ref name=”checkbox” />
<interceptor-ref name=”params” />
<interceptor-ref name=”conversionError” />
</interceptor-stack>
5.1.4. <default-interceptor-ref>
- 디폴트 네임스페이스처럼 디폴트 인터셉터가 존재한다.
5.1.5. 인터셉터 설정
- 스트럿츠2는 struts-default.xml에서 다양한 인터셉터를 미리 만들어 두었지만, 개발자가 원하는 형식으로
직접 설정하여 사용할 수 있다.
설정) struts.xml
<interceptors>
<interceptor name=”timer” class=”com.opensymphony.xwork2.interceptor.TimerInterceptor” />
<interceptor name=”logger” class=”com.opensymphony.xwork2.interceptor.LoggingInterceptor” />
</interceptors>
<action name=”HelloWorldAction” class=””>
<interceptor-ref name=”timer” />
<interceptor-ref name=”logger” />
</action>
HelloWorldAction 액션이 실행되기 전/후로 실행될 인터셉터를 지정하기 위해서 <interceptor-ref> 요소를
사용한다. 이렇게 설정된 인터셉터는 설정 파일에 기술되는 순서대로 호출되며, 사용자 요청에 대해 적용.
수행(execute() 메소드를 통해)이 끝나면 해당 함수 호출은 설정 파일에 기술된 인터셉터의 순서에 따라
역순으로 올라간다. 메모리 할당 제거를 비롯하여 액션 처리를 마무리한다.
ActionInvocation 객체인 invocation로 invoke() 메소드를 호출하여 Action을 수행하고 Interceptor에 기술된
액션 후 처리를 진행한다. 진행순서가 역순이다.
5.1.6. 커스텀 인터셉터
- 스트럿츠2는 커스텀 인터셉터를 위해서 Interceptor 인터페이스를 제공한다.
Interceptor 인터페이스는 init() – 인터셉터를 초기화, destroy() – 인터셉터에서 사용한 리소스를 반환,
Intercept() – 액션 수행하기 전에 수행할 일과 액션 수행 후에 할 일을 기술하고, 그 경계선에는
전달인자이며 ActionInvocation 객체인 invocation로 invoke() 메소드를 호출한다.
Init(), destroy()는 대체로 요청할 때마다 인스턴스를 생성하는 것이 아니라 미리 인스턴스를 띄워놓고
서비스하는 용도로 사용된다.
- 커스텀 인터셉터를 위한 AbstractInterceptor 추상 클래스
인터셉터에 특별히 초기화하거나 종료 시 자원을 반납할 필요가 없다면 init()나 destroy()를 오버라이딩하여
구현하는 것이 불편하기에 AbstractInterceptor 클래스를 제공한다.
AbstractInterceptor 클래스는 Interceptor 인터페이스의 구현 클래스로 init(), destroy() 메소드를 오버라이딩한
후 아무런 구현도 하지 않았다.
5.1.7. 인터셉터 종류
-
인터셉터 |
설명 |
alias |
앨리어스 인터셉터는 실행될 때 넘어온 요청 파라미터의 이름을 다른 이름으로 사용할 수 있도록 한다. |
chaining |
체인 인터셉터는 이전에 실행된 액션의 속성을 현재 액션에서 사용하도록 한다. 많은 경우 이 인터셉터는 리절트 체인과 함께 사용된다. |
checkbox |
체크박스가 체크되지 않은 상태에서도 체크박스의 상태값을 넘겨줄 수 있도록 한다. 체크를 하지 않은 체크박스는 false 상태로 인식한다. |
conversionError |
타입 변환 오류가 발생할 경우 오류 메시지를 등록하도록 한다. |
createSession |
HTTP 세션을 자동으로 생성한다. |
debugging |
개발자에 따라 커스터마이즈된 다양한 디버깅 화면을 제공한다. |
exeAndWait |
백그라운드에서 액션이 실행되는 동안 사용자로 하여금 잠시 대기하도록 하는 화면을 보여주는 인터셉터이다. |
exception |
액션 실행 중에 발생한 예외 케이스에 대해 결과에 반영한다. 자동으로 예외 처리 핸들러에 리다이렉션 하도록 한다. |
fileUpload |
파일 업로드 기능을 지원하는 인터셉터이다. |
i18n |
사용자 세션에 따라서 선택된 지역화 설정을 유지한다. |
store |
ValidationAware 인터페이스를 구현함으로써 메시지를 저장하고 검색한다. 필드 에러나 액션에서 발생하는 에러 메시지를 저장한다. |
scopedModelDriven |
ScopedModelDriven 인터페이스를 구현하는 액션을 위해서 특정 스코프에 해당하는 모델 객체를 저장하고 검색하는 기능이다. |
profile |
액션에 로깅될 프로파일 정보를 제공한다. |
Scope |
세션 또는 어플리케이션 스코프에서 액션의 상태를 저장하고 검색한다. |
servletConfig |
다양한 서블릿 기반 정보에 대해 접근하는 액션을 제공한다. |
staticParams |
정적으로 정의된 값을 액션에 설정한다. 예를 들면, 액션 설정 시 param 태그를 사용하여 설정한 값들이 이에 해당한다. |
roles |
현재 유저가 설정된 역할 중 하나에 해당할 때에만 액션이 실행되도록 한다. |
token |
중복된 폼 전송을 방지하기 위해서 올바른 토큰을 가지고 있는지를 체크한다. |
tokenSession |
토큰과 유사하다. 하지만, 올바르지 않은 토큰이 주어진 경우는 전송된 데이터를 세션에 저장한다. |
validation |
액션에 전달할 데이터를 검증하는 기능을 제공한다. |
5.1.8. 인터셉터 스택 종류
-
인터셉터 스택 |
인터셉터 |
설명 |
BasicStack |
Exception, servletConfig, prepare, checkbox, params, conversionError |
최소 환경에서 사용될 인터셉터 |
Validation WorkflowStack |
basicStack, validation, workflow |
이전에 실해된 액션의 속성을 현재 액션에서 사용하도록 한다. 많은 경우에 이 인터셉터는 결과 타입 (result type) chain 과 함께 사용된다. |
fileUploadStack |
fileUpload, basicStack |
기본 스택에 파일 업로딩 기능 추가 |
modelDrivenStack |
modelDriven, basicStack |
기본 스택에 모델 기능 추가 |
chainStack |
Chain, basicStack |
기본 스택에 체인 기능 추가 |
i18nStack |
i18n, basicStack |
기본 스택에 지역화 유지 기능 추가 |
paramPrepareParamsStack |
Exception, alias, params, servletConfig, Prepare, i18n, chain, modelDriven, fileUpload, checkbox, staticParams, params, conversionError, validation, workflow |
Pre-action 메소드 호출을 포함하는 복잡한 스택을 제공한다. Params 인터셉터는 두 번 적용된다. 먼저 prepare() 메소드가 호출되기 이전에 파라미터를 제공하며, 두 번째는 prepare 단계에서 검색된 객체들에게 파라미터를 다시 제공하려 할 때 사용된다. |
defaultStack |
Exception, alias, servletConfig, prepare, i18n, chain, debugging, profiling, modelDriven, scoped, ModelDriven, fileUpload, checkbox, staticParams, params, conversionError, validation, workflow |
디버깅과 프로파일링을 포함하는 완전한 스택 기능을 제공 |
executeAndWaitStack |
execAndWait, defaultStack |
실행과 대기 스택을 제공한다. |