본문 바로가기

프레임워크/Struts2

interceptor에 대해

[1] 개요

스트럿츠 2에 도입된 중요한 요소 중에 하나로 Action 객체가 실행하기 전/후에 호출된다.

 

■ 개요

⋅ 액션 단위의 작업을 수행할 때 기존 액션 처리 전과 후에 추가적인 작업을 지원한다.

⋅ 모든 액션 요청(Action Request)에 대해 공통적으로 적용되어야 하는 공통 기능들을 제공하는 모듈

인터셉터의 시작은 ActionInvocation 이 담당한다. ActionInvocation 은 인터셉터 스택에 정의된 인터셉터로 구성된 맵을 가지고 있다.

⋅ 액션 프록시가 ActionInvocation 의 invoke() 메서드를 호출 할 때 인터셉터의 실행이 시작된다.

인터셉터의 작업이 끝나면, 또 다시 ActionInvocation 의 invoke() 메서드를 다시 호출한다. invoke() 에서드는 실행할 추가 인터셉터가 존재하는지 조사한 후 실행할 인터셉터가 존재한다면, 그 인터셉터의 interceptor() 메서드를 호출하는 식으로 인터셉터 체인을 형성한다. 만약 더 실행할 인터셉터가 존재하지 않는다면, 액션을 호출한 후 리절트를 실행한다.

⋅ 사용자가 자신만의 인터셉터를 작성하여 적용할 수 있다.

⋅ 스트럿츠2가 자체적으로 기본적인 인터셉터들은 제공하고 있으며, 디폴트 XML(struts-default.xml) 파일에 정의되어 있다.

 

■ 용도

⋅ 값의 검증

⋅ 사용자 인증처리

⋅ 예외처리

⋅ 파라미터 설정 및 변경

⋅ 복잡한 연산의 감춤

 

인터셉터 스택

⋅ 다수의 인터셉터들을 묶어 정의함으로서, 하나 이상의 인터셉터들이 일괄적으로 적용되도록 해준다.

인터셉터는 정의된 순서대로 적용 된다.

⋅ 기본적인 인터셉터 스택은 디폴트 XML(struts-default.xml) 파일에 정의되어 있다.

⋅ 사용자만의 인터셉터 스택을 정의하여 사용할 수 있다.

⋅ 패키지별 액션별로 적용될 수 있다.

 

또한 Struts2에서는 많은 스택들을 준비해 놓고 있다.

 

가장 많이 사용하는 것은 params 인터셉터로 요청할 때 넘어온 파라미터 값을 해당 Action에 설정하는 일을 한다. 파라미터 이름이 'name' 이라면 Action 객체의 setName() 메서드를 호출하여 파라미터 값을 할 당하며 이름이 'employee.id' 이면 Action객체에 대해 getEmployee().setId() 메서드를 호출한다.

 

interceptor 는 "Stack" Interceptor 를 만들어서 함께 연결될 수 있다. 만약 Action 에서 client의 신뢰성을 체크하고, Action 을 로그 처리하고, 시간을 측정하는 등 이러한 일반적인 기능을 수행하고 자한다면, 동일한 Interceptor Stack 을 만들어 사용할 수 있다.

 

interceptor 는 자바 클래스로 구현되며, 각 Interceptor 는 그 이름이 유일해야 한다. Interceptor 를 쉽게 만들어 사용하고자 한다면, Framework 에 등록하고, 간단한 이름으로 등록하여 사용할 수 있다.

 

<interceptors>

<interceptor name= "security" class= "com.company.security.SecurityInterceptor" />

<interceptor-stack name= "secureStack" >

<interceptor-ref name= "security" />

<interceptor-ref name= "defaultStack" />

</interceptor-stack>

</interceptors>

 

개개의 Interceptor 와 Interceptor Stack 은 Interceptor Stack 에 정의된 모든 순서에 맞게 함께 사용되어 질 수 있다. Struts 2 Framework 은 Stack 에 정의된 순서대로 각 Interceptor 를 호출할 것이다.

 

대부분의 어플리케이션은 default Interceptor Stack 을 정의한다.

 

<default-interceptor-ref name="secureStack"/>

하지만 각 Action 은 자신의 local stack 을 정의할 수 있습니다.

 

<action name= "VelocityCounter" class= "org.apache.struts2.example.counter.SimpleCounter" >

<result name= "success" > ... </result>

<interceptor-ref name= "defaultComponentStack" />

</action>

 

디폴트 환경설정(struts-default.xml) 에서 default Interceptor Stack 을 설정하며, 대부분의 어플리케이션에서 잘 동작을 한다.

 

[2] interceptor 관련 태그

■ <interceptors>

⋅ package를 시작할 때는 그 package에 소속된 action들이 사용할 interceptor를 먼저 정의하는데 이를 <interceptors>안에 기술한다.

⋅ <interceptors>안에는 Configuring Interceptor는 <interceptor>tag로, Stacking Interceptor는 <interceptor-stack>를 사용한다.

 

■ <interceptor>

인터셉터 스택에서 참조할 인터셉터를 등록하는 태그이다.

⋅ attribute

name: 인터셉터 ID

class: 인터셉터의 소스파일의 경로, 만약 struts-default.xml에 등록되어있는 interceptor 라면 class를 쓸 필요가 없다.

 

■ <interceptor-stack>

⋅ 여러개의 인터셉터는 하나의 스택으로 만드는 태그이다.

⋅ <interceptor-ref>를 사용하여 등록된 인터셉터를 stack 화 한다.

⋅ attribute

name: 인터셉터 스택 ID

 

■ <interceptor-ref>

⋅ <interceptor-stack>태그 안에서는 <interceptor-ref>를 사용하여 등록된 인터셉터를 stack 화 한다.

⋅ <action>태그에서 실제로 인터셉터가 사용될때는 <interceptor-ref>에 name에 위에서 등록한 인터셉터인터셉터-스택 이름을 등록한다.

 

[3] 정의된 interceptor

⋅ alias : 요청 사이에 서로 다른 이름을 가진 비슷한 파라미터들을 컨버팅 한다.

⋅ chain : 이전 액션의 프로퍼티들을 현재 액션에서 사용 할 수 있게 한다. 이전 액션 정의에서 <result type="chain"> 과 함께 사용한다.

⋅ conversionError : ActionContext에서 액션의 필드 오류로 변환한다.

⋅ createSession : 자동으로 HttpSession을 생성한다. Token Interceptor와 같이 HttpSession이 적절하게 작동하도록 요구하는 인터셉터들에 유용하다.

⋅ debugging : 페이지 뒷단에 데이터를 출력할 수 있는 몇몇 디버깅 화면을 제공한다.

⋅ externalRef

⋅ execAndWait : 백그라운드에서 액션을 실행하고 대기 상태 페이지를 사용자에게 즉각적으로 보낸다.

⋅ exception : exception들을 결과(Result)에 매핑 한다.

⋅ fileUpload : 파일 업로드를 쉽게 할 수 있게 지원한다.

⋅ i18n : 사용자 세션에 대한 지역정보를 기억한다.

⋅ logger : 액션의 이름을 출력한다.

⋅ modelDriven : 액션이 ModelDriven 인터페이스를 구현하였다면 getModel() 결과를 ValueStack에 넣어 준다.

⋅ scopedModelDriven : 액션이 ScopedModelDriven 인터페이스를 구현하였다면 인터셉터는 스코프로부터 Interceptor driven 모델을 저장 처리하고, setModel()을 호출하여 액션에 저장한다.

⋅ params : 요청 파라미터들을 액션에 저장한다.

⋅ prepare : 액션이 Preparable 인터페이스를 구현하였다면 prepare() 메서드를 호출한다.

⋅ staticParams : struts.xml에 정의된 파라미터 값들을 액션에 저장한다. <action> 태그 의 직속 자식으로 <param> 태그가 있다.

⋅ scope : 액션 상태 값을 세션 또는 애플리케이션 스코프에 저장하는 간단한 메커니즘

⋅ servletConfig : HttpServletRequest와 HttpServletResponse를 다루는 맵을 엑세스할 수 있게 한다.

⋅ timer : 인터셉터와 뷰 처리를 포함하여 액션의 작업 처리 시간을 출력한다.

⋅ token : 액션 내에 유효한 토큰이 존재하는 지 검사하고 폼을 이중으로 submit 하는 것을 방지한다.

⋅ tokenSession : Token Interceptor와 같다, 그러나 유효하지 않은 토큰을 가지고 있을 때 세션 내에 submit 된 데이터를 저장한다.

⋅ validation : action-validation.xml 내에 정의된 validator를 사용하여 유효성 검사를 한다.

⋅ workflow : 액션 클래스 내의 validator() 메서드를 호출한다. 액션에서 오류가 발생했다면 그것은 input 뷰로 리턴 한다.

⋅ store : 인터페이스를 구현한 액션에 대한 액션 메시지 / 오류, 필드 오류을 저장하고 처리한다.

⋅ checkbox : 체크되지 않은 체크박스를 감지할 수 있는 코드를 자동으로 추가하고 디폴트 값(보통(false)을 가진 파라미터들로 그들을 추가한다. submit 되지 않은 체크박스를 감지하기 위해서 특별한 이름을 가진 히든(hidden) 필드를 사용한다.

⋅ profiling : 파라미터를 통해서 프로파일링을 작동시킨다.

⋅ roles : 사용자가 올바른 JAAS 권한을 가진다면 액션은 실행된다.

⋅ cookie : 액션에 설정가능한 '이름/값'을 가지는 쿠키 삽입(2.0.7부터 추가)

⋅ autowiring

⋅ sessionAutowiring

 

[4] Prepare Interceptor

프리페이 인터셉터는 Preparable 인터페이스를 구현한 액션의 prepare() 메서드를 호출하는 기능을 제공한다. 이 인터셉터는 액션 메서드를 호출하기 전에 수행해야 할 비지니스 로직을 수행할 필요가 있을 때 매우 유용하다.

 

<action name="someAction" class="ex1.SomeAction">

<interceptor-ref name="params" />

<interceptor-ref name="prepare" />

<interceptor-ref name="basicStack" />

<result>/ex1/res.jsp</result>

</action>

 

[5] Model-Driven Interceptor

모델 드리븐 인터셉터는 ModelDriven 인터페이스를 구현한 액션 클래스를 지켜본 후 액션의 getModel() 메서드를 호출하여 getModel() 메서드가 반환하는 객체의 프로퍼티를 valueStack 에 저장한다. 모델 드리븐 인터셉터로 파라미터를 모델에 적용하려면 Stack Parameters Interceptor 와 Parameters Interceptor 전에 위치해야 한다.

 

만약 모델이 널 값이 아니라면 스택에 저장한다. 또한 모델 드리븐 액션을 생성하려면 액션 클래스가 ModelDriven 인터페이스를 구현하고, Object 타입의 model 프로퍼티를 생성하거나 최소한 public Object getModel() 메서드를 만들어야 한다.

 

<action name="someAction" class="ex1.SomeAction">

<interceptor-ref name="modelDriven" />

<interceptor-ref name="basikStack" />

<result>/ex1/res.jsp</result>

</action>

 

[6] Parameter Interceptor

파라미터 인터셉터는 모든 파라미터를 밸류 스택에 저장한다. 이 인터셉터는 ActionContext의 getParameter() 메서드로 모든 파라미터를 얻은 후 ValueStack의 setValue(String, Object) 메서드를 호출하여 valueStack 에 저장한다.

 

<action name="someAction" class="ex1.SomeAction">

<interceptor-ref name="params" />

<result>/ex1/res.jsp</result>

</action>

 

[7] fileupload Interceptor

파일 업로드 인터셉터의 역할은 폼의 enctype 속성이 "multipart/form-data" 값으로 설정된 페이지에 <s:file /> 태그를 사용하여 파일을 첨부하여 포스트 방식으로 submit 했을 때 요청으로부터 멀티 파트 래퍼 (MultiPartWrapper) 클래스 객체를 생성한다. 멀티 파트 래퍼 클래스로부터 포함된 각 파일의 파라미터의 파일 내용, 컨텐츠 타입, 파일 이름을 액션 컨텍스트의 파라미터 객체에 저장한다.

호출한 <s:file name="upload" /> 태그는 액션 클래스의 프로퍼티의 javaio.File 타입의 프로퍼티 'upload'와 매핑한다.

 

업로드한 파일의 로컬 파일명은 특정 명명 규칙에 의한 String 타입의 프토퍼티가 액션 클래스에 정의되어 있을 경우 자동으로 그 프로퍼티에 저장한다.

 

⋅ <s:file /> 태그의 name 속성 명= " 액션 클래스의 java.io.File 타입 프로퍼티 명"

⋅ 로컬파일명을 저장할 프로퍼트 명= " 액션 클래스의 java.lang.String 타입 프로퍼티 명 " + "FileName"( ex :-> uploadFileName)

⋅ 컨텐츠 타입을 저장할 프로퍼티 명= "액션 클래스의 java.lang.String 타입 프로퍼티 명 " + "ContentType" ( ex : upload -> uploadContentType)

[출처] http://blog.naver.com/cain007/63143609