리전 ID
REGION_ID
는 앱을 만들 때 선택한 리전을 기준으로 Google에서 할당하는 축약된 코드입니다. 일부 리전 ID는 일반적으로 사용되는 국가 및 주/도 코드와 비슷하게 표시될 수 있지만 코드는 국가 또는 주/도와 일치하지 않습니다. 2020년 2월 이후에 생성된 앱의 경우 REGION_ID.r
이 App Engine URL에 포함됩니다. 이 날짜 이전에 만든 기존 앱의 경우 URL에서 리전 ID는 선택사항입니다.
리전 ID에 대해 자세히 알아보세요.
Java 웹 애플리케이션은 배포 설명자 파일을 사용하여 URL이 서블릿에 매핑되는 방법, 인증이 필요한 URL 등의 정보를 확인합니다. 이 파일은 이름이 web.xml
이고 웹 애플리케이션에 대한 서블릿 사양 중 일부입니다.
web.xml
배포 설명자에 대한 자세한 내용은 서블릿 사양을 참조하세요.
Java 8에서 마이그레이션 중이며 지원되는 최신 Java 버전에서 기존 번들 서비스를 사용해야 하는 경우 <app-engine-apis>
요소를 추가하고 web.xml
파일에서 true
로 설정합니다.
<app-engine-apis>true</app-engine-apis>
배포 설명자
웹 애플리케이션의 배포 설명자는 애플리케이션의 클래스, 리소스, 구성 및 웹 서버가 이를 사용해서 웹 요청을 처리하는 방법을 기술합니다. 웹 서버는 애플리케이션에 대한 요청이 수신되면 배포 설명자를 사용하여 요청의 URL을 해당 요청을 처리해야 하는 코드에 매핑합니다.
배포 설명자는 이름이 web.xml
인 파일입니다. 이 파일은 앱의 WAR에서 WEB-INF/
디렉터리에 위치하며, 루트 요소가 <web-app>
인 XML 파일입니다.
다음 web.xml
예시는 EE10(기본값)에서 버전 21 이상, EE8에서는 버전 21, 그 이전에는 버전 17 이하에 대해 모든 URL 경로(/*
)를 서블릿 클래스 mysite.server.ComingSoonServlet
에 매핑합니다. 기본 구성에서 지원되는 최신 버전을 사용하려면 Jakarta
네임스페이스를 포함하도록 애플리케이션 서블릿 및 종속 항목을 업데이트해야 합니다. 구성 옵션에 대한 자세한 내용은 기존 애플리케이션 업그레이드를 참조하세요.
v21 이상(EE10)
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0">
<runtime>java21</runtime> <!-- or another supported version -->
<servlet>
<servlet-name>comingsoon</servlet-name>
<servlet-class>mysite.server.ComingSoonServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>comingsoon</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
v21(EE8)
<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">
<runtime>java21</runtime>
<system-properties> <!-- run your apps on EE8 -->
<property name="appengine.use.EE8" value="true"/>
</system-properties>
<servlet>
<servlet-name>comingsoon</servlet-name>
<servlet-class>mysite.server.ComingSoonServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>comingsoon</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
v17 이하
<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">
<runtime>java17</runtime>
<servlet>
<servlet-name>comingsoon</servlet-name>
<servlet-class>mysite.server.ComingSoonServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>comingsoon</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
애플리케이션을 여러 서비스로 분할하는 경우 각 서비스가 자체 구성 매개변수를 갖습니다.
서블릿 및 URL 경로
web.xml
은 URL 경로와 해당 경로의 요청을 처리하는 서블릿 사이의 매핑을 정의합니다. 웹 서버는 이 구성을 사용하여 특정한 요청을 처리할 서블릿을 식별하고 요청 메서드에 해당하는 클래스 메서드를 호출합니다. 예를 들어 HTTP GET
요청에는 doGet()
메서드를 사용합니다.
URL을 서블릿에 매핑하려면 <servlet>
요소로 서블릿을 선언한 후 <servlet-mapping>
요소로 URL 경로에서 서블릿 선언으로 이어지는 매핑을 정의합니다.
서블릿을 선언하는 <servlet>
요소에는 파일의 다른 요소에서 서블릿을 참조하는 데 사용할 이름, 서블릿에 사용할 클래스, 초기화 매개변수가 포함됩니다. 동일한 클래스에 서로 다른 초기화 매개변수를 사용하여 여러 서블릿을 선언할 수 있습니다. 각 서블릿의 이름은 배포 설명자 내에서 고유해야 합니다.
<servlet> <servlet-name>redteam</servlet-name> <servlet-class>mysite.server.TeamServlet</servlet-class> <init-param> <param-name>teamColor</param-name> <param-value>red</param-value> </init-param> <init-param> <param-name>bgColor</param-name> <param-value>#CC0000</param-value> </init-param> </servlet> <servlet> <servlet-name>blueteam</servlet-name> <servlet-class>mysite.server.TeamServlet</servlet-class> <init-param> <param-name>teamColor</param-name> <param-value>blue</param-value> </init-param> <init-param> <param-name>bgColor</param-name> <param-value>#0000CC</param-value> </init-param> </servlet>
<servlet-mapping>
요소는 URL 패턴 및 URL이 해당 패턴과 일치하는 요청에 사용할 선언된 서블릿의 이름을 지정합니다. URL 패턴의 시작 또는 끝 부분에 별표(*
)를 사용하여 0개 이상의 모든 문자를 나타낼 수 있습니다. URL 패턴에서는 문자열 중간의 와일드 카드를 지원하지 않으며, 패턴 하나에 여러 와일드 카드를 허용하지 않습니다. 패턴은 도메인 이름 다음에 오는 슬래시(/
)부터 URL의 전체 경로와 일치하며, 슬래시 자체도 여기에 포함됩니다. URL 경로는 마침표(.
)로 시작될 수 없습니다.
<servlet-mapping> <servlet-name>redteam</servlet-name> <url-pattern>/red/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>blueteam</servlet-name> <url-pattern>/blue/*</url-pattern> </servlet-mapping>
이 예시에서 URL http://www.example.com/blue/teamProfile
에 대한 요청을 TeamServlet
클래스가 처리하며 teamColor
매개변수는 blue
, bgColor
매개변수는 #0000CC
입니다. 서블릿은 ServletRequest 객체의 getPathInfo()
메서드를 사용하여 와일드 카드와 일치하는 URL 경로의 일부를 가져올 수 있습니다.
서블릿에서 초기화 매개변수에 액세스하려면 자신의 getServletConfig()
메서드를 사용하여 서블릿 구성을 가져온 후 구성 객체에 대해 getInitParameter()
메서드를 호출하면서 매개변수 이름을 인수로 사용합니다.
String teamColor = getServletConfig().getInitParameter("teamColor");
JSP
앱에서 JSP(자바 서버 페이지)를 사용하여 웹페이지를 구현할 수 있습니다. JSP는 HTML 등의 정적 콘텐츠와 자바 코드를 함께 사용하여 정의된 서블릿입니다.
App Engine은 JSP 자동 컴파일 및 URL 매핑을 지원합니다. 애플리케이션의 WAR(WEB-INF/
외부)에서 파일 이름이 .jsp
로 끝나는 JSP 파일은 자동으로 서블릿 클래스로 컴파일되며, WAR 루트를 기준으로 JSP 파일 경로에 해당하는 URL 경로에 매핑됩니다. 예를 들어 WAR의 register/
하위 디렉터리에 이름이 start.jsp
인 JSP 파일이 앱에 포함된 경우 App Engine이 이를 컴파일하여 URL 경로 /register/start.jsp
로 매핑합니다.
JSP가 URL에 매핑되는 방식을 더 세밀하게 제어하려면 배포 설명자의 <servlet>
요소에 매핑을 선언하여 명시적으로 지정할 수 있습니다. <servlet-class>
요소 대신 WAR 루트의 JSP 파일에 대한 경로로 <jsp-file>
요소를 지정합니다. JSP의 <servlet>
요소는 초기화 매개변수를 포함할 수 있습니다.
<servlet> <servlet-name>register</servlet-name> <jsp-file>/register/start.jsp</jsp-file> </servlet> <servlet-mapping> <servlet-name>register</servlet-name> <url-pattern>/register/*</url-pattern> </servlet-mapping>
<taglib>
요소로 JSP 태그 라이브러리를 설치할 수 있습니다. 태그 라이브러리에는 JSP 태그 라이브러리 설명자(TLD) 파일의 경로(<taglib-location>
) 및 JSP에서 로드할 라이브러리를 선택하는 데 사용하는 URI(<taglib-uri>
)가 포함됩니다. 자바 서버 페이지 표준 태그 라이브러리(JSTL)는 App Engine에서 제공하므로 직접 설치할 필요가 없습니다.
<taglib> <taglib-uri>/escape</taglib-uri> <taglib-location>/WEB-INF/escape-tags.tld</taglib-location> </taglib>
보안 및 인증
App Engine 애플리케이션은 사용자 인증에 Google 계정을 사용할 수 있습니다. 앱은 Google Accounts API로 사용자의 로그인 여부를 감지하고, 현재 로그인한 사용자의 이메일 주소를 가져오고, 로그인 및 로그아웃 URL을 생성할 수 있습니다. 또한 배포 설명자를 사용하여 Google 계정을 기준으로 URL 경로에 대한 액세스 제한을 지정할 수 있습니다.
<security-constraint>
요소는 패턴과 일치하는 URL에 대한 보안 제약조건을 정의합니다. 로그인하지 않은 사용자가 액세스하는 URL의 경로에 보안 제약조건이 있는 경우 App Engine은 사용자를 Google 계정 로그인 페이지로 리디렉션합니다. 사용자가 로그인에 성공하거나 새 계정을 등록하면 Google 계정에서 사용자를 애플리케이션 URL로 다시 리디렉션합니다. 앱에서 이외에 별도의 조치를 취하지 않아도 로그인한 사용자만 URL에 액세스할 수 있습니다.
보안 제약조건에는 어떠한 Google 계정 사용자가 경로에 액세스할 수 있는지를 지정하는 승인 제약조건이 포함됩니다. 승인 제약조건에서 사용자 역할을 *
로 지정하면 Google 계정으로 로그인한 모든 사용자가 URL에 액세스할 수 있습니다. 제약조건에서 사용자 역할을 admin
으로 지정하면 등록된 애플리케이션 개발자만 URL에 액세스할 수 있습니다. admin
역할을 사용하면 사이트의 관리자 전용 섹션을 쉽게 구축할 수 있습니다.
<security-constraint> <web-resource-collection> <web-resource-name>profile</web-resource-name> <url-pattern>/profile/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>*</role-name> </auth-constraint> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>admin</web-resource-name> <url-pattern>/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> </security-constraint>
App Engine은 배포 설명자에서 커스텀 보안 역할(<security-role>
) 또는 대체 인증 메커니즘(<login-config>
)을 지원하지 않습니다.
보안 제약조건은 정적 파일과 서블릿에 모두 적용됩니다.
보안 URL
App Engine은 REGION_ID.r.appspot.com
도메인을 사용하는 URL에 HTTPS를 사용하여 보안 연결을 지원합니다. 요청에서 HTTPS를 사용하여 URL에 액세스하며 web.xml
파일에 해당 URL이 HTTPS를 사용하도록 구성된 경우, 요청 데이터와 응답 데이터가 모두 발신자에 의해 암호화된 후에 전송되고 수신자는 데이터를 수신한 후 복호화합니다. 보안 연결은 연락처 정보, 비밀번호, 개인 메시지 등의 고객 데이터를 보호하는 데 유용합니다.
URL에 HTTPS를 사용하도록 선언하려면 보안 및 인증의 설명에 따라 배포 설명자에 보안 제약조건을 설정하면서 <user-data-constraint>
의 <transport-guarantee>
를 CONFIDENTIAL
로 지정합니다.
예를 들면 다음과 같습니다.
<security-constraint> <web-resource-collection> <web-resource-name>profile</web-resource-name> <url-pattern>/profile/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint>
전송 보장이 CONFIDENTIAL
인 URL에 비보안 HTTP를 사용하는 요청은 자동으로 HTTPS를 사용하여 같은 URL로 리디렉션됩니다.
JSP, 정적 파일을 포함하여 모든 URL에 CONFIDENTIAL
전송 보장을 사용할 수 있습니다.
개발용 웹 서버는 HTTPS 연결을 지원하지 않습니다. 전송 보장이 무시되므로 개발용 웹 서버에 대한 일반 HTTP 연결을 사용하여 HTTPS용으로 의도된 경로를 테스트할 수 있습니다.
https://1.latest.your_app_id.REGION_ID.r.appspot.com/
과 같이 버전이 지정된 appspot.com URL을 사용하여 앱의 HTTPS 핸들러를 테스트하면 브라우저에서 HTTPS 인증서가 해당 특정 도메인 경로에 대해 서명되지 않았다는 경고가 표시됩니다. 인증서를 해당 도메인용으로 수락하면 페이지가 정상적으로 로드됩니다. 사용자가 https://your_app_id.REGION_ID.r.appspot.com/
에 액세스할 때는 인증서 경고가 표시되지 않습니다.
버전이 지정된 appspot.com URL 중에서 이러한 문제가 나타나지 않도록 설계된 대체 형식을 사용할 수도 있습니다. 하위 도메인 구성요소를 구분하는 마침표를 '-dot-
' 문자열로 바꾸면 됩니다. 예를 들어 앞의 예시에서 인증서 경고 없이 액세스하려면 https://VERSION_ID-dot-default-dot-PROJECT_ID.REGION_ID.r.appspot.com
을 사용합니다.
Google 계정 로그인 및 로그아웃은 애플리케이션의 URL이 구성된 방식과 무관하게 항상 보안 연결을 사용하여 수행됩니다.
위에서 설명한 것처럼 보안 제약조건은 정적 파일과 서블릿에 모두 적용됩니다. 전송 보장도 여기에 포함됩니다.
참고: HTTPS 프로토콜을 사용하여 앱에 요청을 보내는 것이 좋습니다. Google은 appspot.com
에서 호스팅되는 이중 와일드 카드 도메인에 SSL 인증서를 발급하지 않습니다. 따라서 HTTPS를 사용하는 경우 아래의 예와 같이 '.' 대신 '-dot-' 문자열을 사용하여 하위 도메인을 구분해야 합니다. 사용자의 커스텀 도메인 또는 HTTP 주소에는 간단히 '.'를 사용할 수 있습니다.
시작 파일 목록
사이트의 URL이 WAR에 포함된 정적 파일 또는 JSP에 대한 경로를 나타내는 경우 디렉터리 경로에 유용한 기능을 부여하는 것이 좋습니다.
계정 비밀번호를 확인하고자 URL 경로 /help/accounts/password.jsp
를 방문하는 사용자는 계정 시스템에 대한 정보를 알려주는 페이지를 찾기 위해 /help/accounts/
를 방문하려고 할 수 있습니다. 배포 설명자는 아직 서블릿에 명시적으로 매핑되지 않은 WAR 하위 디렉터리를 나타내는 경로에 사용자가 액세스할 때 서버에서 시도할 파일 이름 목록을 지정할 수 있습니다. 서블릿 사양에서는 이를 welcome file list
라고 부릅니다.
예를 들어 사용자가 URL 경로 /help/accounts/
에 액세스하면 배포 설명자에 있는 다음 <welcome-file-list>
요소는 서버가 URL이 존재하지 않음을 보고하기 전에 help/accounts/index.jsp
및 help/accounts/index.html
이 있는지 확인하도록 지시합니다.
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
필터
필터는 서블릿과 같이 요청에 대해 작동하는 클래스이지만 다른 필터 또는 서블릿이 요청을 계속 처리하도록 허용할 수 있습니다. 필터는 로깅, 특화된 인증 검사, 서블릿 호출 전 요청 또는 응답 객체 주석 처리와 같은 보조 태스크를 수행할 수 있습니다. 필터를 사용하면 배포 설명자에서 요청 처리 태스크를 구성할 수 있습니다.
다음 필터 구현 예시는 메시지를 로깅하고, EE10의 버전 21 이상(기본값), EE8의 버전 21, 버전 17 이하에 대해 배포 설명자에 기술된 대로 다른 필터 또는 서블릿을 포함할 수 있는 체인을 따라 제어를 전달합니다. 기본 구성에서 지원되는 최신 버전을 사용하려면 Jakarta
네임스페이스를 포함하도록 애플리케이션 서블릿 및 종속 항목을 업데이트해야 합니다. 구성 옵션에 대한 자세한 내용은 기존 애플리케이션 업그레이드를 참조하세요.
v21 이상(EE10)
이 필터 클래스는 doFilter()
메서드를 사용하여 jakarta.servlet.Filter
인터페이스를 구현합니다.
package mysite.server;
import java.io.IOException;
import java.util.logging.Logger;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
public class LogFilterImpl implements Filter {
private FilterConfig filterConfig;
private static final Logger log = Logger.getLogger(LogFilterImpl.class.getName());
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
log.warning("Log filter processed a " + getFilterConfig().getInitParameter("logType")
+ " request");
filterChain.doFilter(request, response);
}
public FilterConfig getFilterConfig() {
return filterConfig;
}
public void init(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
public void destroy() {}
}
v21(EE8)
이 필터 클래스는 doFilter()
메서드를 사용하여 javax.servlet.Filter
인터페이스를 구현합니다.
package mysite.server;
import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class LogFilterImpl implements Filter {
private FilterConfig filterConfig;
private static final Logger log = Logger.getLogger(LogFilterImpl.class.getName());
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
log.warning("Log filter processed a " + getFilterConfig().getInitParameter("logType")
+ " request");
filterChain.doFilter(request, response);
}
public FilterConfig getFilterConfig() {
return filterConfig;
}
public void init(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
public void destroy() {}
}
v17 이하
이 필터 클래스는 doFilter()
메서드를 사용하여 javax.servlet.Filter
인터페이스를 구현합니다.
package mysite.server;
import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class LogFilterImpl implements Filter {
private FilterConfig filterConfig;
private static final Logger log = Logger.getLogger(LogFilterImpl.class.getName());
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
log.warning("Log filter processed a " + getFilterConfig().getInitParameter("logType")
+ " request");
filterChain.doFilter(request, response);
}
public FilterConfig getFilterConfig() {
return filterConfig;
}
public void init(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
public void destroy() {}
}
배포 설명자에 필터를 구성하는 방법은 서블릿과 비슷합니다. <filter>
요소로 필터를 선언한 후 <filter-mapping>
요소로 URL 패턴에 매핑하면 됩니다. 필터를 다른 서블릿에 직접 매핑할 수도 있습니다.
<filter>
요소에는 <filter-name>
, <filter-class>
, 선택사항 <init-param>
요소가 포함됩니다.
<filter> <filter-name>logSpecial</filter-name> <filter-class>mysite.server.LogFilterImpl</filter-class> <init-param> <param-name>logType</param-name> <param-value>special</param-value> </init-param> </filter>
<filter-mapping>
요소에는 선언된 필터의 이름과 일치하는 <filter-name>
이 포함되고, URL에 필터를 적용하는 <url-pattern>
요소 또는 선언된 서블릿의 이름과 일치하며 해당 서블릿이 호출될 때마다 필터를 적용하는 <servlet-name>
요소 중 하나가 포함됩니다.
<!-- Log for all URLs ending in ".special" --> <filter-mapping> <filter-name>logSpecial</filter-name> <url-pattern>*.special</url-pattern> </filter-mapping> <!-- Log for all URLs that use the "comingsoon" servlet --> <filter-mapping> <filter-name>logSpecial</filter-name> <servlet-name>comingsoon</servlet-name> </filter-mapping>
오류 핸들러
배포 설명자를 사용하여 오류가 발생할 때 서버가 사용자에게 전송하는 내용을 맞춤설정할 수 있습니다. 서버는 특정 HTTP 상태 코드를 전송하려고 할 때 또는 서블릿에서 특정 자바 예외가 발생할 때 대체 페이지 위치를 표시할 수 있습니다.
<error-page>
요소는 HTTP 오류 코드 값이 있는 <error-code>
요소(예: 500
) 또는 예상되는 예외의 클래스 이름이 있는 <exception-type>
요소(예: java.io.IOException
)를 포함합니다. 또한 오류가 발생할 때 표시할 리소스의 URL 경로를 갖는 <location>
요소가 포함됩니다.
<error-page> <error-code>500</error-code> <location>/errors/servererror.jsp</location> </error-page>
다음 오류 조건에 대해서는 커스텀 오류 핸들러를 구성할 수 없습니다.
- URL에 대해 정의된 서블릿 매핑이 없을 때
404
응답 페이지 403
할당량 오류 페이지- App Engine 내부 오류 이후에 표시되는
500
서버 오류 페이지
지원되지 않는 web.xml 기능
다음 web.xml 기능은 App Engine에서 지원되지 않습니다.
- App Engine은 서블릿 선언에
<load-on-startup>
요소를 지원합니다. 그러나 실제로 로드되는 시점은 웹 서버 인스턴스가 첫 번째 요청을 처리할 때이며, 그 이전에는 로드되지 않습니다. - 배포 설명자의 일부 요소는 IDE에서 사람이 읽을 수 있는 표시 이름, 설명, 아이콘을 사용할 수 있습니다. App Engine은 이러한 항목을 사용하지 않고 무시합니다.
- App Engine은 JNDI 환경 변수(
<env-entry>
)를 지원하지 않습니다. - App Engine은 EJB 리소스(
<resource-ref>
)를 지원하지 않습니다. - 서블릿, 서블릿 컨텍스트 또는 필터 삭제 알림은 지원되지 않습니다.
<distributable>
요소는 무시됩니다.<run-at>
을 사용한 서블릿 예약은 지원되지 않습니다.