Java 网络应用程序使用部署描述符文件来判断网址如何映射到 servlet、哪些网址需要验证,以及其他信息。此文件名为 web.xml,且位于应用程序的 WAR 中的 WEB-INF/ 目录中。web.xml 是网络应用程序的 servlet 标准的一部分。
有关 web.xml 标准的详细信息,请参阅 Metawerx web.xml 参考 Wiki、ebLogic web.xml 元素参考以及 Servlet 规范。
网络应用程序的部署描述符描述应用程序的类、资源和配置以及网络服务器使用这些类、资源和配置为网络请求提供服务的方式。当网络服务器收到应用程序的请求时,它使用部署描述符来将请求的网址映射到应处理该请求的代码。
部署描述符是名为 web.xml 的文件。它位于应用程序的 WAR 中的 WEB-INF/ 目录中。该文件是 XML 文件,其根元素是 <web-app>。
以下是将所有网址路径 (/*) 映射到 servlet 类 mysite.server.ComingSoonServlet 的简单 web.xml 实例:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<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>
web.xml 定义网址路径与处理关于这些路径的请求的 servlet 之间的映射。网络服务器使用此配置来识别处理给定请求的 servlet 并调用对应于请求方法的类方法(例如,HTTP GET 请求对应的 doGet() 方法)。
要将网址映射到 servlet,请使用 <servlet> 元素声明 servlet,然后通过 <servlet-mapping> 元素定义从网址路径到 servlet 声明的映射。
<servlet> 元素声明 servlet,包括用于文件中其他元素引用该 servlet 的名称、用于 servlet 的类,以及初始化参数。您可以使用具有不同初始化参数的同一类来声明多个 servlet。每一 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> 元素指定一个网址模式以及用于网址匹配该模式的请求的声明 servlet 的名称。网址模式可以在模式的开头或结尾使用星号 (*) 来指示任何零或多个字符。(该标准不支持在字符串的中间有通配符,并且不允许在一个模式有多个通配符。)模式匹配网址的完整路径,域名后以正斜杠开始并包括正斜杠 (/)。
<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>
在本示例中,对于网址 http://www.example.com/blue/teamProfile 的请求由 TeamServlet 类处理,其中 teamColor 参数等于 blue,bgColor 参数等于 #0000CC。使用 ServletRequest 对象的 getPathInfo() 方法,servlet 可获取网址路径和通配符匹配的部分。
注意:静态文件、逐字向用户提供的文件(例如图像、CSS 或 JavaScript)从部署描述符中所提到的路径分开处理。对于匹配指向 WAR 中视为静态文件的文件的路径的网址路径的请求将服务于该文件,而和部署描述符中的 servlet 和过滤条件映射无关。可使用 appengine-web.xml 文件从那些视为静态文件的文件中排除文件。
servlet 可通过使用其 getServletConfig() 方法获取 servlet 配置,然后将初始化参数的名称作为参数调用配置对象上的 getInitParameter() 方法来访问其初始化参数。
String teamColor = getServletConfig().getInitParameter("teamColor");
应用程序可以使用 JavaServer 页面 (JSP) 来实现网页。JSP 是用混合 Java 代码的静态内容(例如 HTML)定义的 servlet。
App Engine 支持 JSP 的自动编译和网址映射。应用程序的 WAR(WEB-INF/ 以外)中的文件名以 .jsp 结尾的 JSP 文件自动编译为 servlet 类,并映射到等于从 WAR 根目录指向 JSP 文件的路径的网址路径。例如,如果应用程序在其 WAR 中的名为 register/ 的子目录中有名为 start.jsp 的 JSP 文件,App Engine 会将其编译并映射到网址路径 /register/start.jsp。
如果您希望对 JSP 映射到网址的方式进行更多的控制,可以通过在部署描述符中用 <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>)。请注意,App Engine 提供 JavaServer 页面标准标签库 (JSTL),因此无需对其安装。
<taglib>
<taglib-uri>/escape</taglib-uri>
<taglib-location>/WEB-INF/escape-tags.tld</taglib-location>
</taglib>
App Engine 应用程序可使用 Google 帐户进行用户验证。应用程序可使用 Google 帐户 API 来检测用户是否登录、获取当前登录的用户的电子邮件地址,并生成登录和退出网址。应用程序可使用部署描述符根据 Google 帐户指定网址路径的访问限制。
<security-constraint> 元素定义与模式匹配的网址的安全约束。如果用户访问了路径有安全约束的网址但用户没有登录,App Engine 会自动将用户重定向到 Google 帐户登录页面。在成功登录或注册新的帐户后,Google 帐户会将用户重定向回应用程序网址。应用程序无需做其他任何事即可确保只有登录用户可以访问网址。
安全约束包含一个指定哪些 Google 帐户用户可以访问路径的授权约束。如果授权约束指定 * 的用户角色,则使用 Google 帐户登录的任何用户都可以访问该网址。如果约束指定 admin 的用户角色,则仅应用程序的注册开发人员(管理员)可以访问该网址。通过 admin 角色可轻松构建网站的仅限管理员部分。
<security-constraint>
<web-resource-collection>
<url-pattern>/profile/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<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>)。
安全约束适用于静态文件以及 servlet。
对于使用 *.appspot.com 域的网址,Google App Engine 支持通过 HTTPS 的安全连接。当请求使用 HTTPS 访问网址时,请求数据和响应数据都在传输前由发送器加密,然后在接收后由接收器解密。安全连接有利于保护客户数据,如联系人信息、密码和私人消息。
注意:Google 企业应用套件域目前不支持 HTTPS。HTTPS 支持限于通过 *.appspot.com 域访问的应用程序。在 Google 企业应用套件域上访问 HTTPS 网址将返回“找不到主机”错误,而使用 HTTP 访问处理程序仅接受 HTTPS 的网址(参见下文)将返回 HTTP 403“禁止访问”错误。您可以为了安全链接到具有 *.appspot.com 域的 HTTPS 网址并为网站其余部分使用企业应用套件域和 HTTP。
在您可以为应用程序使用安全网址之前,您必须使用 <ssl-enabeld>true</ssl-enabled> 元素在应用程序的 appengine-web.xml 文件中启用安全网址。有关此文件的详细信息,请参阅应用程序配置:启用安全网址。
要声明网址应使用 HTTPS,需使用 <transport-guarantee> 为 CONFIDENTIAL 的 <user-data-constraint> 在部署描述符中设置一个安全约束(如安全和验证中所述),如下所示:
<security-constraint>
<web-resource-collection>
<url-pattern>/profile/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
传输保证为 CONFIDENTIAL 的使用 HTTP(非安全)网址的请求将自动重定向到使用 HTTPS 的同一网址。
安全连接比不安全连接占用更多的 CPU 和带宽,因此更昂贵。安全连接也比非安全连接慢。
任何网址都可使用 CONFIDENTIAL 传输保证,包括 JSP 和静态文件。
开发网络服务器不支持 HTTPS 连接。其忽略传输保证,因此可使用与开发网络服务器的常规 HTTP 连接测试专用于 HTTPS 的路径。
当使用版本化 appspot.com 网址(例如 https://1.latest.app-id.appspot.com/)测试您的应用程序的 HTTPS 处理程序时,您的浏览器将警告没有为该特定域路径注册 HTTPS 证书。如果您接受该域的证书,则将成功载入页面。用户在访问 https://app-id.appspot.com/ 时不会显示证书警告。
Google 帐户登录和退出将始终使用安全连接执行,和应用程序的网址如何配置无关。
如上所述,安全约束适用于静态文件以及 servlet。此包括传输保证。
当针对您的网站的网址表示指向您的 WAR 中的静态文件或 JSP 的路径时,指向目录的路径也能够做一些有用的事往往是一个好主意。访问网址路径 /help/accounts/password.jsp 以获得有关帐户密码的信息的用户可能尝试访问 /help/accounts/ 来找到介绍帐户系统文档的页面。部署描述符可以指定服务器将在用户访问表示 WAR 子目录(尚未显式映射到 servlet)的路径时尝试的文件名的列表。servlet 标准将此称为“欢迎文件列表”。
例如,如果用户访问网址路径 /help/accounts/,部署描述符中的以下 <welcome-file-list> 元素将告知服务器在报告该网址不存在之前检查是否有 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>
过滤条件是如 servlet 一样作用于请求的类,但是可以允许其他过滤条件或 servlet 继续请求的处理。过滤条件可以执行辅助任务,如日志记录、执行专用验证检查,或在调用 servlet 之前对请求或响应对象进行批注。过滤条件允许您从部署描述符组合请求处理任务。
过滤条件类实现 javax.servlet.Filter 接口,包括 doFilter() 方法。以下是记录消息并将控制沿链(如部署描述符所描述,其可包括其他过滤条件或 servlet)向下传递的简单过滤条件实现:
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LogFilterImpl implements Filter {
private FilterConfig filterConfig;
private static final Logger log = Logger.getLogger(LogFilterImpl.class.getName());
public void doFilter(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws IOException, ServletException {
log.info("Log filter processed a " +
getServletConfig().getInitParameter("logType") +
" request");
filterConfig.doFilter(request, response);
}
public FilterConfig getFilterConfig() {
return filterConfig;
}
public void setFilterConfig(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
}
类似于 servlet,您可通过使用 <filter> 元素声明过滤条件,然后使用 <filter-mapping> 元素将其映射到网址模式来在部署描述符中配置过滤条件。您还可以将过滤条件直接映射到其他 servlet。
<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-pattern> 元素,或用于在调用 servlet 时应用过滤条件的与声明的 servlet 的名称匹配的 <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 状态代码或在 servlet 引发特殊 Java 异常时显示替代页面位置。
<error-page> 元素包含具有 HTTP 错误代码值的 <error-code> 元素(例如 500)或具有预期异常的类名称的 <exception-type> 元素(例如 java.io.IOException)。其还含有包含资源的网址路径的 <location> 元素,以显示错误的发生时间。
<error-page>
<error-code>500</error-code>
<location>/errors/servererror.jsp</location>
</error-page>
注意:截至本文档编写之时,还无法为某些错误条件配置自定义错误处理程序。具体来说,您不可自定义没有为网址定义 servlet 映射时的 404 响应代码、进而不能自定义 403 配额错误页面,或由 App Engine 内部错误导致的 500 服务器错误。
App Engine 支持 servlet 声明的 <load-on-startup> 元素。但是,载入实际上是在网络服务器实例处理第一个请求期间发生,而不是在之前。
App Engine 支持 <mime-mapping> 元素以指定要用于文件名以某些扩展名结尾的资源的 MIME 类型。然而,MIME 映射只适用于 servlet,而不适用于静态文件。静态文件使用一个从文件名扩展名到 MIME 类型的映射的固定列表。
一些部署描述符元素可以采用人可读的显示名称、描述和图标以用于 IDE 中。App Engine 并不使用这些,并将其忽略。
App Engine 不支持 JNDI 环境变量 (<env-entry>)。
App Engine 不支持 EJB 资源 (<resource-ref>)。
忽略 <distributable> 元素。
不支持使用 <run-at> 的 servlet 调度。