본문 바로가기

Struts/Struts Programming

[Struts] 커스텀 인터셉터

반응형

■ 커스텀 인터셉터

 스트럿츠 2 프레임워크에는 사용자와 웹 애플리케이션의 목적에 따라 매우 편리하게 커스텀 인터셉터를 생성할 수 있다.

커스텀 인터셉터는 인터페이스 형태로 선언되어 있는 인터셉터를 상속하여 사용자가 원하는 대로 확장하는 것을 의미한다.


01) 커스텀 인터셉터를 위한 Interceptor 인터페이스

 ① init( ) 메소드는 인터셉터를 초기화하기 위한 방법

 ② destroy( ) 메소드는 인터셉터에서 사용한 리소스들을 반환하기 위한 메소드이다.

  ※ init( )나 destroy( )는 대체로 요청할 때마다 인스턴스를 생성하는 것이 아니라

     미리 인스턴스를 띄워놓고 서비스하는 용도로 사용된다.


 ③ interceptor( ) 메소드는 액션 수행하기 전에 수행할 일과 액션 수행 후에 수행할 일을 기술하고,

    그 경계선에는 전달자이며 ActionInvocation 객체인 invocation로 invoke( ) 메소드를 호출해야 한다.

 

02) 커스텀 인터셉터를 위한 AbstractInterceptor 추상 클래스

※ 인터셉터에 특별히 초기화하거나 종료 시 자원을 반납할 필요가 없다면 init( )이나 destory( )를 오버라이딩 하여

    구현하는 것이 불편할 것이다. 스트럿츠는 이러한 불편함을 없애기 위해서 AbstractInterceptor 클래스를 제공한다.


 -. AbstractInterceptor 클래스는 Interceptor 인터페이스의 구현 클래스로 init( )과 destory( ) 메소드를 오버라이딩 한 후

   아무런 구현도 하지 않는다.

 -. 그렇기 때문에 AbstractInterceptor 클래스의 서브 클래스로 인터셉터 클래스를 작성할 경우에는 init( )와 destroy( )

    메소드를 오버라이딩하지 않아도 되고, intercept( ) 메소드만 오버라이딩 하면 된다.


① AbstractInterceptor 클래스의 서브클래스 작성

  OneInterceptor.java

public class OneInterceptor extends AbstractInterceptor {

    private static Log log = LogFactory.getLog(TimerInterceptor.class);
   
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
       

        // 액션 수행하기 전에 처리할 일(전처리)

        String result = invocation.invoke();                  ..............................①
       

        // 액션 수행 후 처리할 일(후처리)      
        return result;
    }
}


 -. AbstractInterceptor 클래스의 서브 클래스로 작성한 커스텀 인터셉터는 액션 인보케이션에 의해서 호출되는

    intercept() 메소드를 오버라이딩해야 한다.

 -. intercept() 메소드 내부에 액션 수행하기 전에 수행할 일과 액션 수행 후에 수행할 일의 경계선에서 전달인자인

    AbstractInterception 객체가 invocation로 invoke( ) 메소드를 호출해야 한다.

 -. 액션 실행을 위한 대행자인 액션 프록시가 필터 디스패처에 의행 생성된다. 이렇게 생성된 액션프록시는 액션 인보케이션을 생성하여

    액션 실행에 앞서 인터셉터를 찾아서 호출하도록 한다.

 -. 액션 프록시는 액션 인보케이션의 invoke( ) 메소드를 호출하고, 액션 인보케이션은 인터셉터 스펙 중 실행할 다음 인터셉터가 있다면

    그 인터셉터의 intercept( ) 메소드를 호출한다.

 -. 인터셉터의 intercept( ) 메소드는 파라미터로 넘어온 액션 인보케이션의 invoke( )메소드를 다시 호출함으로서 체인을 형성한다.

 -. 커스텀 인터셉터가 인터셉터 스택중에 다음에 실행할 인터셉터가 있는지 확인하여 호출할 인터셉터가 존재할 때까지 체인 형태로

    운영되도록 하기 위해서는 위 예에서처럼 invocation.invoke( ) 메소드()를 호출해야 한다.



② 두 개의 인터셉터(OneInterceptor, TwoInterceptor) 설정

  struts.xml

    <package name = "ch05" extends = "struts-default">
        <interceptors>
            <interceptor name = "oneInterceptor" class = "interceptor.OneInterceptor"/>
            <interceptor name = "twoInterceptor" class = "interceptor.TwoInterceptor"/>
        </interceptors>
        <action name = "HelloWorld" class = "action.HelloWorld">
            <interceptor-ref name = "timer"/>
            <result name = "success">/helloWorld.jsp</result>
        </action>       
    </package>
</struts>

 커스텀 인터셉터 수행 순서


 -. 인터셉터는 액션 수행 전 설정 파일에 기술되는 순서대로 인터셉터의 전처리가 이루어진다.

 -. 액션 수행 후에는 설정 파일에 기술도니 인터셉터의 순서에 따라 거꾸로 올라가면 인터셉터와 후처리가 진행되는 체인 형태로 운영한다.



 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>Chapter05</display-name>
 
    <!-- 스트럿츠2의 핵심 컨트롤러 역할을 수행하는 FilterDispatcher 클래스로 struts2란 필터를 등록한다. -->
  <filter>
    <filter-name>struts2</filter-name>
    <!-- 스트럿츠2의 핵심 컨트롤러 역할을 수행하는 클래스 -->
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    <init-param>
        <!-- 스트럿츠2에서 한글 처리 -->
        <param-name>struts.i18n.encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
  </filter>
 
  <!-- URL 확장자가 action일 때 FilterDispatcher 필터가 실행되도록 매핑한다. -->
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
 
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>
 Chapter05/WebContet/WEB-INF/src/interceptor/OneInterceptor.java

package interceptor;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.TimerInterceptor;

// 인터셉터는 액션 단위의 작업을 수행할 때 기존 액션 처리 전후에 추가적인 작업을 지원한다.
// 인터셉터는 정의된 순서대로 실행되고 더 이상 실행할 인터셉터가 없을 때 액션이 실행되고 그 다음에 리절트가 실행된다.
// 액션 인보케이션은 여러 개의 인터셉터로 구성된 인터셉터 스택 형태로 구현된다.
// 액션 프로시가 인보케이션의 invoke()메소드를 호출하면 인터세버가 실행된다.

public class OneInterceptor extends AbstractInterceptor {

    private static Log log = LogFactory.getLog(TimerInterceptor.class);
   
    // 액션 인보케이션의 invoke() 메소드 내에서는 인터셉터 스택에 정의된 인터셉터가 존재한다면
    // 인터셉터의 intercept() 멧소드를 호출한다.
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
       
        Date toDay = new Date();
        log.info("OneInterceptor의 선처리 : 실행날짜 : " + toDay + " ms");
       
        long startTime = System.currentTimeMillis();
       
        // intercept() 메소드 내에서는 액션 인보케이션의 invoke() 메소드를 다시 호출한다.
        // 다시 호출된 액션 인보케이션의  invoke() 메소드는 실행할 추가 인터셉터가 존재하는지 조사한 후
        // 실행할 인터셉터가 존재하면 그 인터셉터의 intercept() 메소드를 호출한다.
        // 이런식으로 동작하면서 인터셉터 체인을 형성한다.
        // 만약 더 실행할 인터셉터가 존재하지 않는다면 액션을 호출한 후 리절트를 실행한다.
        String result = invocation.invoke();
        long executeTime = System.currentTimeMillis() - startTime;
        log.info("OneInterceptor의 후 처리 : 실행시간 : " + executeTime + " ms");
       
        return result;
    }
}

 Chapter05/WebContet/WEB-INF/src/interceptor/TwoInterceptor.java

package interceptor;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.TimerInterceptor;

public class TwoInterceptor extends AbstractInterceptor {

    private static Log log = LogFactory.getLog(TimerInterceptor.class);
   
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
       
        Date toDay = new Date();
        log.info("TwoInterceptor의 선처리 : 실행날짜 : " + toDay + " ms");
       
        long startTime = System.currentTimeMillis();
        String result = invocation.invoke();
        long executeTime = System.currentTimeMillis() - startTime;
        log.info("TwoInterceptor의 후 처리 : 실행시간 : " + executeTime + " ms");
       
        return result;
    }
}

 Chapter05/WebContet/WEB-INF/src/action/HelloWorld

package action;


// 액션 클래스를 POJO 형태로 작성
public class HelloWorld {
   
     private String message;

     public String getMessage() {
        return message;
     }


     public String execute() throws Exception {
         
      this.message = "Hello, World!";
      return "success";
     }
}

 Chapter05/WebContet/WEB-INF/src/struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation/DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
   
<struts>
    <package name = "ch05" extends = "struts-default">
        <interceptors>
            <interceptor name = "oneInterceptor" class = "interceptor.OneInterceptor"/>
            <interceptor name = "twoInterceptor" class = "interceptor.TwoInterceptor"/>
        </interceptors>
        <action name = "HelloWorld" class = "action.HelloWorld">
            <interceptor-ref name = "timer"/>
            <result name = "success">/helloWorld.jsp</result>
        </action>       
    </package>
</struts>
 helloWorld.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello, World!</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>

 출력결과(http://localhost:8181/Chapter05/HelloWorld.action)












 ①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮

반응형

'Struts > Struts Programming' 카테고리의 다른 글

[Struts] 스트럿츠 2의 핵심 기능  (0) 2012.11.06
[Struts] 인터셉터의 종류  (0) 2012.09.12
[Struts] 인터셉터란?  (0) 2012.09.11
[Struts] 인터셉터란?  (0) 2012.09.11
[Struts] 스트럿츠 2 아키텍처  (0) 2012.09.06