Run as a servlet

Aspectran을 서블릿 컨테이너에 서블릿으로 등록함으로써, 전통적인 웹애플리케이션을 구축하는 데 사용될 수도 있습니다.

1. 서블릿 컨테이너

Aspectran은 알려진 여러 서블릿 컨테이너에 하나의 서블릿으로 등록되어 구동될 수 있으며, Java 8 이상 버전을 사용하고 있다면 다음과 같은 서블릿 스펙을 안정적으로 지원합니다.

서블릿 스펙JSP 스펙
4.02.3
3.12.3
3.02.2

2. 서블릿 구성

web.xml 파일에 Aspectran 구동을 위한 서블릿 구성 방법에 대해 설명합니다.

2.1 초기화 파라메터 정의

먼저 Aspectran의 구동 환경을 구성하기 위한 초기화 파라메터 aspectran:config를 정의합니다. 초기화 파라메터 aspectran:config에 할당된 값은 APON(Aspectran Parameters Object Notation) 형식으로 작성되었습니다.

참고로 APON(Aspectran Parameters Object Notation)은 JSON 과 표기법이 유사하며, 매개 변수로 전달되는 설정 값의 작성 및 읽기가 용이하도록 Aspectran을 위해 특별히 개발된 새로운 표기법입니다.

<context-param>
  <param-name>aspectran:config</param-name>
  <param-value>
    context: {
        root: /WEB-INF/config/app-config.xml
        encoding: utf-8
        resources: [
        ]
        scan: [
            com.aspectran.demosite
        ]
        autoReload: {
            reloadMode: hard
            scanIntervalSeconds: 5
            enabled: false
        }
        profiles: {
        }
    }
    scheduler: {
        startDelaySeconds: 10
        waitOnShutdown: true
        enabled: false
    }
    web: {
        uriDecoding: utf-8
        defaultServletName: default
        exposals: {
            +: /
            +: /examples**
            +: /terminal**
            +: /skylark**
        }
    }
  </param-value>
</context-param>

2.1.1 context 파라메터

Aspectran을 구동하는데 꼭 필요한 설정 값을 가지고 있습니다.

파라메터설명기본 값
context.root루트 구성 파일의 경로/WEB-INF/aspectran/root.xml
context.encoding환경 구성 파일의 인코딩 방식을 지정 
context.resourcesAspectran이 관리하는 리소스 파일의 경로를 배열로 지정 
context.scan자바 어노테이션에 의한 환경 구성을 위해 스캔할 패키지 경로를 배열로 지정 
context.autoReload.reloadMethodsoft: 환경 구성만 재로딩 가능, hard: 환경 구성 및 Java 리소스까지 재로딩 가능soft
context.autoReload.observationInterval환경 구성 파일 또는 Java 리소스의 변경을 관찰하는 시간 간격을 초 단위로 지정10
context.autoReload.startup환경 구성 파일 또는 자바 리소스 파일이 변경될 경우 환경 구성을 백그라운드에서 자동으로 재로딩을 할 지 여부를 지정false

2.1.2 scheduler 파라메터

스케쥴러 서비스가 동작하는데 필요한 설정 값을 가지고 있습니다.

파라메터설명기본 값
scheduler.startDelaySeconds스케쥴러 서비스가 기동되기 전 지연 시간을 초 단위로 지정5
scheduler.waitOnShutdown스케쥴러 서비스가 종료될때 실행중인 모든 Job이 종료되기를 기다릴지 여부를 지정false
scheduler.startup스케쥴러 서비스를 구동할지 여부를 지정false

2.2 WebServiceListener

다음으로 WebServiceListener는 초기화 파라메터 aspectran:config의 값에 따라 내부적으로 DefaultWebService를 초기화 합니다. 한 번 초기화 된 DefaultWebService 인스턴스는 이후 여러 WebActivityServlet에서 사용될 수 있습니다.

<listener>
  <listener-class>com.aspectran.web.startup.listener.WebServiceListener</listener-class>
</listener>

2.3 WebActivityFilter

WebActivityServlet 서블릿으로 전달되는 요청을 필터링하기 위한 WebActivityFilter 필터를 정의합니다.

    <filter>
        <filter-name>web-activity-filter</filter-name>
        <filter-class>com.aspectran.web.startup.filter.WebActivityFilter</filter-class>
        <init-param>
            <param-name>bypasses</param-name>
            <param-value>
                /assets/**
            </param-value>
        </init-param>
    </filter>

WebActivityFilter 필터는 기본적으로 HttpServletRequestActivityRequestWrapper로 랩핑을 해 줌으로써, Aspectran에 의해 파싱된 요청 데이터 및 모든 활동 결과 데이터에 대한 접근이 가능하게 됩니다.

또한 WebActivityServlet 서블릿이 처리할 필요가 없는 우회할 요청 URI를 bypasses 파라메터에 지정함으로써, WebActivityServlet 서블릿의 부담을 덜어 줄 수가 있습니다. 주로 스태틱 리소스의 경로를 지정하고, 해당 URL는 DefaultServlet이 처리하게 됩니다.

2.4 WebActivityServlet

클라이언트의 모든 요청을 처리하기 위한 서블릿 WebActivityServletweb-activity-servlet 이름으로 정의하고, / 경로와 맵핑합니다.

<servlet>
  <servlet-name>web-activity-servlet</servlet-name>
  <servlet-class>com.aspectran.web.startup.servlet.WebActivityServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>web-activity-servlet</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

WebActivityServlet 서블릿이 처리하지 못한 요청은 DefaultServlet이 처리할 수 있도록 설정되어 있으며, DefaultServlet 서블릿의 이름은 default로 지정했습니다. DefaultServlet 서블릿의 이름을 명시적으로 지정하지 않을 경우 잘 알려진 웹어플리케이션 서버의 종류에 따라 자동으로 판단합니다. 위의 초기화 파라메터에 다음과 같이 DefaultServlet 서블릿의 이름을 지정된 것을 볼 수 있습니다.

    web: {
        uriDecoding: utf-8
        defaultServletName: default
        exposals: {
            +: /
            +: /examples**
            +: /terminal**
            +: /skylark**
        }
    }

3. 예제 프로젝트

다음은 Aspectran의 예제 기능을 시연하기 위해 구축된 데모 사이트 소스가 저장되어 있는 GitHub 저장소입니다.

Repository on GitHub

데모 사이트는 구글 앱엔진에 통하여 임시로 서비스 되고 있으며, 다음 URL을 통하여 접속이 가능합니다.

Aspectran Demo Site

참고로 구글 앱엔진은 웹 애플리케이션 서버로 Jetty를 사용하고 있으며, Jetty를 위한 web.xml 파일은 다음과 같이 작성되었습니다.

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <display-name>demo-site</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <context-param>
        <param-name>aspectran:config</param-name>
        <param-value>
            context: {
                root: /WEB-INF/config/app-config.xml
                encoding: utf-8
                resources: [
                ]
                scan: [
                    com.aspectran.demosite
                ]
                autoReload: {
                    reloadMode: hard
                    scanIntervalSeconds: 5
                    enabled: false
                }
                profiles: {
                }
            }
            scheduler: {
                startDelaySeconds: 10
                waitOnShutdown: true
                enabled: false
            }
            web: {
                uriDecoding: utf-8
                exposals: {
                    +: /
                    +: /examples**
                    +: /terminal**
                    +: /skylark**
                }
            }
        </param-value>
    </context-param>
    <listener>
        <listener-class>com.aspectran.web.startup.listener.AspectranServiceListener</listener-class>
    </listener>
    <filter>
        <filter-name>web-activity-filter</filter-name>
        <filter-class>com.aspectran.web.startup.filter.WebActivityFilter</filter-class>
        <init-param>
            <param-name>bypasses</param-name>
            <param-value>
                /assets/**
            </param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>web-activity-filter</filter-name>
        <url-pattern>/</url-pattern>
        <servlet-name>web-activity-servlet</servlet-name>
    </filter-mapping>
    <servlet>
        <servlet-name>web-activity-servlet</servlet-name>
        <servlet-class>com.aspectran.web.startup.servlet.WebActivityServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>web-activity-servlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>