(来源于:http://blog.csdn.net/jamyy2000/archive/2006/04/11/658898.aspx)
1
定义头和根元素
部署描述符文件就像所有 XML 文件一样,必须以一个 XML 头开始。这个头声明可以使用的 XML 版本并给出文件的字符编码。
DOCYTPE 声明必须立即出现在此头之后。这个声明告诉服务器适用的 servlet 规范的版本(如 2.2 或 2.3 )并指定管理此文件其余部分内容的语法的 DTD(Document Type Definition ,文档类型定义 ) 。
所有部署描述符文件的顶层(根)元素为 web-app 。请注意, XML 元素不像 HTML ,他们是大小写敏感的。因此, web-App 和 WEB-APP 都是不合法的, web-app 必须用小写。
2 部署描述符文件内的元素次序
XML 元素不仅是大小写敏感的,而且它们还对出现在其他元素中的次序敏感。例如, XML 头必须是文件中的第一项, DOCTYPE 声明必须是第二项,而 web- app 元素必须是第三项。在 web-app 元素内,元素的次序也很重要。服务器不一定强制要求这种次序,但它们允许(实际上有些服务器就是这样做的)完全拒绝执行含有次序不正确的元素的 Web 应用。这表示使用非标准元素次序的 web.xml 文件是不可移植的。
下面的列表给出了所有可直接出现在 web-app 元素内的合法元素所必需的次序。例如,此列表说明 servlet 元素必须出现在所有 servlet-mapping 元素之前。请注意,所有这些元素都是可选的。因此,可以省略掉某一元素,但不能把它放于不正确的位置。
l icon icon 元素指出 IDE 和 GUI 工具用来表示 Web 应用的一个和两个图像文件的位置。
l display-name display-name 元素提供 GUI 工具可能会用来标记这个特定的 Web 应用的一个名称。
l description description 元素给出与此有关的说明性文本。
l context-param context-param 元素声明应用范围内的初始化参数。
l filter 过滤器元素将一个名字与一个实现 javax.servlet.Filter 接口的类相关联。
l filter-mapping 一旦命名了一个过滤器,就要利用 filter-mapping 元素把它与一个或多个 servlet 或 JSP 页面相关联。
l listener servlet API 的版本 2.3 增加了对事件监听程序的支持,事件监听程序在建立、修改和删除会话或 servlet 环境时得到通知。 Listener 元素指出事件监听程序类。
l servlet 在向 servlet 或 JSP 页面制定初始化参数或定制 URL 时,必须首先命名 servlet 或 JSP 页面。 Servlet 元素就是用来完成此项任务的。
l servlet-mapping 服务器一般为 servlet 提供一个缺省的 URL : http://host/webAppPrefix/servlet/ServletName 。但是,常常会更改这个 URL ,以便 servlet 可以访问初始化参数或更容易地处理相对 URL 。在更改缺省 URL 时,使用 servlet-mapping 元素。
l session-config 如果某个会话在一定时间内未被访问,服务器可以抛弃它以节省内存。可通过使用 HttpSession 的 setMaxInactiveInterval 方法明确设置单个会话对象的超时值,或者可利用 session-config 元素制定缺省超时值。
l mime-mapping 如果 Web 应用具有想到特殊的文件,希望能保证给他们分配特定的 MIME 类型,则 mime-mapping 元素提供这种保证。
l welcom-file-list welcome-file-list 元素指示服务器在收到引用一个目录名而不是文件名的 URL 时,使用哪个文件。
l error-page error-page 元素使得在返回特定 HTTP 状态代码时,或者特定类型的异常被抛出时,能够制定将要显示的页面。
l taglib taglib 元素对标记库描述符文件( Tag Libraryu Descriptor file )指定别名。此功能使你能够更改 TLD 文件的位置,而不用编辑使用这些文件的 JSP 页面。
l resource-env-ref resource-env-ref 元素声明与资源相关的一个管理对象。
l resource-ref resource-ref 元素声明一个资源工厂使用的外部资源。
l security-constraint security-constraint 元素制定应该保护的 URL 。它与 login-config 元素联合使用
l login-config 用 login-config 元素来指定服务器应该怎样给试图访问受保护页面的用户授权。它与 sercurity-constraint 元素联合使用。
l security-role security-role 元素给出安全角色的一个列表,这些角色将出现在 servlet 元素内的 security-role-ref 元素的 role-name 子元素中。分别地声明角色可使高级 IDE 处理安全信息更为容易。
l env-entry env-entry 元素声明 Web 应用的环境项。
l ejb-ref ejb-ref 元素声明一个 EJB 的主目录的引用。
l ejb-local-ref ejb-local-ref 元素声明一个 EJB 的本地主目录的应用。
3 分配名称和定制的 UL
在 web.xml 中完成的一个最常见的任务是对 servlet 或 JSP 页面给出名称和定制的 URL 。用 servlet 元素分配名称,使用 servlet-mapping 元素将定制的 URL 与刚分配的名称相关联。
3.1 分配名称
为了提供初始化参数,对 servlet 或 JSP 页面定义一个定制 URL 或分配一个安全角色,必须首先给 servlet 或 JSP 页面一个名称。可通过 servlet 元素分配一个名称。最常见的格式包括 servlet-name 和 servlet-class 子元素(在 web-app 元素内),如下所示:
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>moreservlets.TestServlet</servlet-class>
</servlet>
这表示位于 WEB-INF/classes/moreservlets/TestServlet 的 servlet 已经得到了注册名 Test 。给 servlet 一个名称具有两个主要的含义。首先,初始化参数、定制的 URL 模式以及其他定制通过此注册名而不是类名引用此 servlet 。其次 , 可在 URL 而不是类名中使用此名称。因此,利用刚才给出的定义, URL http://host/webAppPrefix/servlet/Test 可用于 http://host/webAppPrefix/servlet/moreservlets.TestServlet 的场所。
请记住: XML 元素不仅是大小写敏感的,而且定义它们的次序也很重要。例如, web-app 元素内所有 servlet 元素必须位于所有 servlet- mapping 元素(下一小节介绍)之前,而且还要位于 5.6 节和 5.11 节讨论的与过滤器或文档相关的元素(如果有的话)之前。类似地, servlet 的 servlet-name 子元素也必须出现在 servlet-class 之前。 5.2 节 " 部署描述符文件内的元素次序 " 将详细介绍这种必需的次序。
例如,程序清单 5-1 给出了一个名为 TestServlet 的简单 servlet ,它驻留在 moreservlets 程序包中。因为此 servlet 是扎根在一个名为 deployDemo 的目录中的 Web 应用的组成部分,所以 TestServlet.class 放在 deployDemo/WEB- INF/classes/moreservlets 中。程序清单 5-2 给出将放置在 deployDemo/WEB-INF/ 内的 web.xml 文件的一部分。此 web.xml 文件使用 servlet-name 和 servlet-class 元素将名称 Test 与 TestServlet.class 相关联。图 5-1 和图 5-2 分别显示利用缺省 URL 和注册名调用 TestServlet 时的结果。
程序清单 5-1 TestServlet.java
package moreservlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/** Simple servlet used to illustrate servlet naming
* and custom URLs.
* <P>
* Taken from More Servlets and JavaServer Pages
* from Prentice Hall and Sun Microsystems Press,
* http://www.moreservlets.com/.
* © 2002 Marty Hall; may be freely used or adapted.
*/
public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String uri = request.getRequestURI();
out.println(ServletUtilities.headWithTitle("Test Servlet") +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H2>URI: " + uri + "</H2>\n" +
"</BODY></HTML>");
}
}
程序清单 5-2 web.xml (说明 servlet 名称的摘录)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
" http://java.sun.com/dtd/web-app_2_3.dtd ">
<web-app>
<!-- … -->
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>moreservlets.TestServlet</servlet-class>
</servlet>
<!-- … -->
</web-app>
3.2 定义定制的 URL
大多数服务器具有一个缺省的 serlvet URL :
http://host/webAppPrefix/servlet/packageName.ServletName 。虽然在开发中使用这个 URL 很方便,但是我们常常会希望另一个 URL 用于部署。例如,可能会需要一个出现在 Web 应用顶层的 URL (如, http: //host/webAppPrefix/Anyname ),并且在此 URL 中没有 servlet 项。位于顶层的 URL 简化了相对 URL 的使用。此外,对许多开发人员来说,顶层 URL 看上去比更长更麻烦的缺省 URL 更简短。
事实上,有时需要使用定制的 URL 。比如,你可能想关闭缺省 URL 映射,以便更好地强制实施安全限制或防止用户意外地访问无初始化参数的 servlet 。如果你禁止了缺省的 URL ,那么你怎样访问 servlet 呢?这时只有使用定制的 URL 了。
为了分配一个定制的 URL ,可使用 servlet-mapping 元素及其 servlet-name 和 url-pattern 子元素。 Servlet- name 元素提供了一个任意名称,可利用此名称引用相应的 servlet ; url-pattern 描述了相对于 Web 应用的根目录的 URL 。 url- pattern 元素的值必须以斜杠( / )起始。
下面给出一个简单的 web.xml 摘录,它允许使用 URL http://host/webAppPrefix/UrlTest 而不是 http://host/webAppPrefix/servlet/Test 或
http: //host/webAppPrefix/servlet/moreservlets.TestServlet 。请注意,仍然需要 XML 头、 DOCTYPE 声明以及 web-app 封闭元素。此外,可回忆一下, XML 元素出现地次序不是随意的。特别是,需要把所有 servlet 元素放在所有 servlet-mapping 元素之前。
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>moreservlets.TestServlet</servlet-class>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name>Test</servlet-name>
<url-pattern>/UrlTest</url-pattern>
</servlet-mapping>
URL 模式还可以包含通配符。例如,下面的小程序指示服务器发送所有以 Web 应用的 URL 前缀开始,以 ..asp 结束的请求到名为 BashMS 的 servlet 。
<servlet>
<servlet-name>BashMS</servlet-name>
<servlet-class>msUtils.ASPTranslator</servlet-class>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name>BashMS</servlet-name>
<url-pattern>/*.asp</url-pattern>
</servlet-mapping>
3.3 命名 JSP 页面
因为 JSP 页面要转换成 sevlet ,自然希望就像命名 servlet 一样命名 JSP 页面。毕竟, JSP 页面可能会从初始化参数、安全设置或定制的 URL 中受益,正如普通的 serlvet 那样。虽然 JSP 页面的后台实际上是 servlet 这句话是正确的,但存在一个关键的猜疑:即,你不知道 JSP 页面的实际类名(因为系统自己挑选这个名字)。因此,为了命名 JSP 页面,可将 jsp-file 元素替换为 servlet-calss 元素,如下所示:
<servlet>
<servlet-name>Test</servlet-name>
<jsp-file>/TestPage.jsp</jsp-file>
</servlet>
命名 JSP 页面的原因与命名 servlet 的原因完全相同:即为了提供一个与定制设置(如,初始化参数和安全设置)一起使用的名称,并且,以便能更改激活 JSP 页面的 URL (比方说,以便多个 URL 通过相同页面得以处理,或者从 URL 中去掉 .jsp 扩展名)。但是,在设置初始化参数时,应该注意, JSP 页面是利用 jspInit 方法,而不是 init 方法读取初始化参数的。
例如,程序清单 5-3 给出一个名为 TestPage.jsp 的简单 JSP 页面,它的工作只是打印出用来激活它的 URL 的本地部分。 TestPage.jsp 放置在 deployDemo 应用的顶层。程序清单 5-4 给出了用来分配一个注册名 PageName ,然后将此注册名与 http://host/webAppPrefix/UrlTest2/anything 形式的 URL 相关联的 web.xml 文件(即, deployDemo/WEB-INF/web.xml )的一部分。
程序清单 5-3 TestPage.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>
JSP Test Page
</TITLE>
</HEAD>
<BODY BGCOLOR="#FDF5E6">
<H2>URI: <%= request.getRequestURI() %></H2>
</BODY>
</HTML>
程序清单 5-4 web.xml (说明 JSP 页命名的摘录)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
" http://java.sun.com/dtd/web-app_2_3.dtd ">
<web-app>
<!-- ... -->
<servlet>
<servlet-name>PageName</servlet-name>
<jsp-file>/TestPage.jsp</jsp-file>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name> PageName </servlet-name>
<url-pattern>/UrlTest2/*</url-pattern>
</servlet-mapping>
<!-- ... -->
</web-app>
4 禁止激活器 servlet
对 servlet 或 JSP 页面建立定制 URL 的一个原因是,这样做可以注册从 init ( servlet )或 jspInit ( JSP 页面)方法中读取得初始化参数。但是,初始化参数只在是利用定制 URL 模式或注册名访问 servlet 或 JSP 页面时可以使用,用缺省 URL http://host/webAppPrefix/servlet/ServletName 访问时不能使用。因此,你可能会希望关闭缺省 URL ,这样就不会有人意外地调用初始化 servlet 了。这个过程有时称为禁止激活器 servlet ,因为多数服务器具有一个用缺省的 servlet URL 注册的标准 servlet ,并激活缺省的 URL 应用的实际 servlet 。
有两种禁止此缺省 URL 的主要方法:
l 在每个 Web 应用中重新映射 /servlet/ 模式。
l 全局关闭激活器 servlet 。
重要的是应该注意到,虽然重新映射每个 Web 应用中的 /servlet/ 模式比彻底禁止激活 servlet 所做的工作更多,但重新映射可以用一种完全可移植的方式来完成。相反,全局禁止激活器 servlet 完全是针对具体机器的,事实上有的服务器(如 ServletExec )没有这样的选择。下面的讨论对每个 Web 应用重新映射 /servlet/ URL 模式的策略。后面提供在 Tomcat 中全局禁止激活器 servlet 的详细内容。
4.1 重新映射 /servlet/URL 模式
在一个特定的 Web 应用中禁止以 http://host/webAppPrefix/servlet/ 开始的 URL 的处理非常简单。所需做的事情就是建立一个错误消息 servlet ,并使用前一节讨论的 url-pattern 元素将所有匹配请求转向该 servlet 。只要简单地使用:
<url-pattern>/servlet/*</url-pattern>
作为 servlet-mapping 元素中的模式即可。
例如,程序清单 5-5 给出了将 SorryServlet servlet (程序清单 5-6 )与所有以 http://host/webAppPrefix/servlet/ 开头的 URL 相关联的部署描述符文件的一部分。
程序清单 5-5 web.xml (说明 JSP 页命名的摘录)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
" http://java.sun.com/dtd/web-app_2_3.dtd ">
<web-app>
<!-- ... -->
<servlet>
<servlet-name>Sorry</servlet-name>
<servlet-class>moreservlets.SorryServlet</servlet-class>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name> Sorry </servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
<!-- ... -->
</web-app>
程序清单 5-6 SorryServlet.java
package moreservlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/** Simple servlet used to give error messages to
* users who try to access default servlet URLs
* (i.e., http://host/webAppPrefix/servlet/ServletName )
* in Web applications that have disabled this
* behavior.
* <P>
* Taken from More Servlets and JavaServer Pages
* from Prentice Hall and Sun Microsystems Press,
* http://www.moreservlets.com/.
* © 2002 Marty Hall; may be freely used or adapted.
*/
public class SorryServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "Invoker Servlet Disabled.";
out.println(ServletUtilities.headWithTitle(title) +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H2>" + title + "</H2>\n" +
"Sorry, access to servlets by means of\n" +
"URLs that begin with\n" +
" http://host/webAppPrefix/servlet/ \n" +
"has been disabled.\n" +
"</BODY></HTML>");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
4.2 全局禁止激活器: Tomcat
Tomcat 4 中用来关闭缺省 URL 的方法与 Tomcat 3 中所用的很不相同。下面介绍这两种方法:
1 .禁止激活器: Tomcat 4
Tomcat 4 用与前面相同的方法关闭激活器 servlet ,即利用 web.xml 中的 url-mapping 元素进行关闭。不同之处在于 Tomcat 使用了放在 install_dir/conf 中的一个服务器专用的全局 web.xml 文件,而前面使用的是存放在每个 Web 应用的 WEB-INF 目录中的标准 web.xml 文件。
因此,为了在 Tomcat 4 中关闭激活器 servlet ,只需在 install_dir/conf/web.xml 中简单地注释出 /servlet/* URL 映射项即可,如下所示:
<!--
<servlet-mapping>
<servlet-name>invoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
-->
再次提醒,应该注意这个项是位于存放在 install_dir/conf 的 Tomcat 专用的 web.xml 文件中的,此文件不是存放在每个 Web 应用的 WEB-INF 目录中的标准 web.xml 。
2 .禁止激活器: Tomcat3
在 Apache Tomcat 的版本 3 中,通过在 install_dir/conf/server.xml 中注释出 InvokerInterceptor 项全局禁止缺省 servlet URL 。例如,下面是禁止使用缺省 servlet URL 的 server.xml 文件的一部分。
<!--
<RequsetInterceptor
className="org.apache.tomcat.request.InvokerInterceptor"
debug="0" prefix="/servlet/" />
-->
5 初始化和预装载 servlet 与 JSP 页面
这里讨论控制 servlet 和 JSP 页面的启动行为的方法。特别是,说明了怎样分配初始化参数以及怎样更改服务器生存期中装载 servlet 和 JSP 页面
部署描述符文件就像所有 XML 文件一样,必须以一个 XML 头开始。这个头声明可以使用的 XML 版本并给出文件的字符编码。
DOCYTPE 声明必须立即出现在此头之后。这个声明告诉服务器适用的 servlet 规范的版本(如 2.2 或 2.3 )并指定管理此文件其余部分内容的语法的 DTD(Document Type Definition ,文档类型定义 ) 。
所有部署描述符文件的顶层(根)元素为 web-app 。请注意, XML 元素不像 HTML ,他们是大小写敏感的。因此, web-App 和 WEB-APP 都是不合法的, web-app 必须用小写。
2 部署描述符文件内的元素次序
XML 元素不仅是大小写敏感的,而且它们还对出现在其他元素中的次序敏感。例如, XML 头必须是文件中的第一项, DOCTYPE 声明必须是第二项,而 web- app 元素必须是第三项。在 web-app 元素内,元素的次序也很重要。服务器不一定强制要求这种次序,但它们允许(实际上有些服务器就是这样做的)完全拒绝执行含有次序不正确的元素的 Web 应用。这表示使用非标准元素次序的 web.xml 文件是不可移植的。
下面的列表给出了所有可直接出现在 web-app 元素内的合法元素所必需的次序。例如,此列表说明 servlet 元素必须出现在所有 servlet-mapping 元素之前。请注意,所有这些元素都是可选的。因此,可以省略掉某一元素,但不能把它放于不正确的位置。
l icon icon 元素指出 IDE 和 GUI 工具用来表示 Web 应用的一个和两个图像文件的位置。
l display-name display-name 元素提供 GUI 工具可能会用来标记这个特定的 Web 应用的一个名称。
l description description 元素给出与此有关的说明性文本。
l context-param context-param 元素声明应用范围内的初始化参数。
l filter 过滤器元素将一个名字与一个实现 javax.servlet.Filter 接口的类相关联。
l filter-mapping 一旦命名了一个过滤器,就要利用 filter-mapping 元素把它与一个或多个 servlet 或 JSP 页面相关联。
l listener servlet API 的版本 2.3 增加了对事件监听程序的支持,事件监听程序在建立、修改和删除会话或 servlet 环境时得到通知。 Listener 元素指出事件监听程序类。
l servlet 在向 servlet 或 JSP 页面制定初始化参数或定制 URL 时,必须首先命名 servlet 或 JSP 页面。 Servlet 元素就是用来完成此项任务的。
l servlet-mapping 服务器一般为 servlet 提供一个缺省的 URL : http://host/webAppPrefix/servlet/ServletName 。但是,常常会更改这个 URL ,以便 servlet 可以访问初始化参数或更容易地处理相对 URL 。在更改缺省 URL 时,使用 servlet-mapping 元素。
l session-config 如果某个会话在一定时间内未被访问,服务器可以抛弃它以节省内存。可通过使用 HttpSession 的 setMaxInactiveInterval 方法明确设置单个会话对象的超时值,或者可利用 session-config 元素制定缺省超时值。
l mime-mapping 如果 Web 应用具有想到特殊的文件,希望能保证给他们分配特定的 MIME 类型,则 mime-mapping 元素提供这种保证。
l welcom-file-list welcome-file-list 元素指示服务器在收到引用一个目录名而不是文件名的 URL 时,使用哪个文件。
l error-page error-page 元素使得在返回特定 HTTP 状态代码时,或者特定类型的异常被抛出时,能够制定将要显示的页面。
l taglib taglib 元素对标记库描述符文件( Tag Libraryu Descriptor file )指定别名。此功能使你能够更改 TLD 文件的位置,而不用编辑使用这些文件的 JSP 页面。
l resource-env-ref resource-env-ref 元素声明与资源相关的一个管理对象。
l resource-ref resource-ref 元素声明一个资源工厂使用的外部资源。
l security-constraint security-constraint 元素制定应该保护的 URL 。它与 login-config 元素联合使用
l login-config 用 login-config 元素来指定服务器应该怎样给试图访问受保护页面的用户授权。它与 sercurity-constraint 元素联合使用。
l security-role security-role 元素给出安全角色的一个列表,这些角色将出现在 servlet 元素内的 security-role-ref 元素的 role-name 子元素中。分别地声明角色可使高级 IDE 处理安全信息更为容易。
l env-entry env-entry 元素声明 Web 应用的环境项。
l ejb-ref ejb-ref 元素声明一个 EJB 的主目录的引用。
l ejb-local-ref ejb-local-ref 元素声明一个 EJB 的本地主目录的应用。
3 分配名称和定制的 UL
在 web.xml 中完成的一个最常见的任务是对 servlet 或 JSP 页面给出名称和定制的 URL 。用 servlet 元素分配名称,使用 servlet-mapping 元素将定制的 URL 与刚分配的名称相关联。
3.1 分配名称
为了提供初始化参数,对 servlet 或 JSP 页面定义一个定制 URL 或分配一个安全角色,必须首先给 servlet 或 JSP 页面一个名称。可通过 servlet 元素分配一个名称。最常见的格式包括 servlet-name 和 servlet-class 子元素(在 web-app 元素内),如下所示:
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>moreservlets.TestServlet</servlet-class>
</servlet>
这表示位于 WEB-INF/classes/moreservlets/TestServlet 的 servlet 已经得到了注册名 Test 。给 servlet 一个名称具有两个主要的含义。首先,初始化参数、定制的 URL 模式以及其他定制通过此注册名而不是类名引用此 servlet 。其次 , 可在 URL 而不是类名中使用此名称。因此,利用刚才给出的定义, URL http://host/webAppPrefix/servlet/Test 可用于 http://host/webAppPrefix/servlet/moreservlets.TestServlet 的场所。
请记住: XML 元素不仅是大小写敏感的,而且定义它们的次序也很重要。例如, web-app 元素内所有 servlet 元素必须位于所有 servlet- mapping 元素(下一小节介绍)之前,而且还要位于 5.6 节和 5.11 节讨论的与过滤器或文档相关的元素(如果有的话)之前。类似地, servlet 的 servlet-name 子元素也必须出现在 servlet-class 之前。 5.2 节 " 部署描述符文件内的元素次序 " 将详细介绍这种必需的次序。
例如,程序清单 5-1 给出了一个名为 TestServlet 的简单 servlet ,它驻留在 moreservlets 程序包中。因为此 servlet 是扎根在一个名为 deployDemo 的目录中的 Web 应用的组成部分,所以 TestServlet.class 放在 deployDemo/WEB- INF/classes/moreservlets 中。程序清单 5-2 给出将放置在 deployDemo/WEB-INF/ 内的 web.xml 文件的一部分。此 web.xml 文件使用 servlet-name 和 servlet-class 元素将名称 Test 与 TestServlet.class 相关联。图 5-1 和图 5-2 分别显示利用缺省 URL 和注册名调用 TestServlet 时的结果。
程序清单 5-1 TestServlet.java
package moreservlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/** Simple servlet used to illustrate servlet naming
* and custom URLs.
* <P>
* Taken from More Servlets and JavaServer Pages
* from Prentice Hall and Sun Microsystems Press,
* http://www.moreservlets.com/.
* © 2002 Marty Hall; may be freely used or adapted.
*/
public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String uri = request.getRequestURI();
out.println(ServletUtilities.headWithTitle("Test Servlet") +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H2>URI: " + uri + "</H2>\n" +
"</BODY></HTML>");
}
}
程序清单 5-2 web.xml (说明 servlet 名称的摘录)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
" http://java.sun.com/dtd/web-app_2_3.dtd ">
<web-app>
<!-- … -->
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>moreservlets.TestServlet</servlet-class>
</servlet>
<!-- … -->
</web-app>
3.2 定义定制的 URL
大多数服务器具有一个缺省的 serlvet URL :
http://host/webAppPrefix/servlet/packageName.ServletName 。虽然在开发中使用这个 URL 很方便,但是我们常常会希望另一个 URL 用于部署。例如,可能会需要一个出现在 Web 应用顶层的 URL (如, http: //host/webAppPrefix/Anyname ),并且在此 URL 中没有 servlet 项。位于顶层的 URL 简化了相对 URL 的使用。此外,对许多开发人员来说,顶层 URL 看上去比更长更麻烦的缺省 URL 更简短。
事实上,有时需要使用定制的 URL 。比如,你可能想关闭缺省 URL 映射,以便更好地强制实施安全限制或防止用户意外地访问无初始化参数的 servlet 。如果你禁止了缺省的 URL ,那么你怎样访问 servlet 呢?这时只有使用定制的 URL 了。
为了分配一个定制的 URL ,可使用 servlet-mapping 元素及其 servlet-name 和 url-pattern 子元素。 Servlet- name 元素提供了一个任意名称,可利用此名称引用相应的 servlet ; url-pattern 描述了相对于 Web 应用的根目录的 URL 。 url- pattern 元素的值必须以斜杠( / )起始。
下面给出一个简单的 web.xml 摘录,它允许使用 URL http://host/webAppPrefix/UrlTest 而不是 http://host/webAppPrefix/servlet/Test 或
http: //host/webAppPrefix/servlet/moreservlets.TestServlet 。请注意,仍然需要 XML 头、 DOCTYPE 声明以及 web-app 封闭元素。此外,可回忆一下, XML 元素出现地次序不是随意的。特别是,需要把所有 servlet 元素放在所有 servlet-mapping 元素之前。
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>moreservlets.TestServlet</servlet-class>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name>Test</servlet-name>
<url-pattern>/UrlTest</url-pattern>
</servlet-mapping>
URL 模式还可以包含通配符。例如,下面的小程序指示服务器发送所有以 Web 应用的 URL 前缀开始,以 ..asp 结束的请求到名为 BashMS 的 servlet 。
<servlet>
<servlet-name>BashMS</servlet-name>
<servlet-class>msUtils.ASPTranslator</servlet-class>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name>BashMS</servlet-name>
<url-pattern>/*.asp</url-pattern>
</servlet-mapping>
3.3 命名 JSP 页面
因为 JSP 页面要转换成 sevlet ,自然希望就像命名 servlet 一样命名 JSP 页面。毕竟, JSP 页面可能会从初始化参数、安全设置或定制的 URL 中受益,正如普通的 serlvet 那样。虽然 JSP 页面的后台实际上是 servlet 这句话是正确的,但存在一个关键的猜疑:即,你不知道 JSP 页面的实际类名(因为系统自己挑选这个名字)。因此,为了命名 JSP 页面,可将 jsp-file 元素替换为 servlet-calss 元素,如下所示:
<servlet>
<servlet-name>Test</servlet-name>
<jsp-file>/TestPage.jsp</jsp-file>
</servlet>
命名 JSP 页面的原因与命名 servlet 的原因完全相同:即为了提供一个与定制设置(如,初始化参数和安全设置)一起使用的名称,并且,以便能更改激活 JSP 页面的 URL (比方说,以便多个 URL 通过相同页面得以处理,或者从 URL 中去掉 .jsp 扩展名)。但是,在设置初始化参数时,应该注意, JSP 页面是利用 jspInit 方法,而不是 init 方法读取初始化参数的。
例如,程序清单 5-3 给出一个名为 TestPage.jsp 的简单 JSP 页面,它的工作只是打印出用来激活它的 URL 的本地部分。 TestPage.jsp 放置在 deployDemo 应用的顶层。程序清单 5-4 给出了用来分配一个注册名 PageName ,然后将此注册名与 http://host/webAppPrefix/UrlTest2/anything 形式的 URL 相关联的 web.xml 文件(即, deployDemo/WEB-INF/web.xml )的一部分。
程序清单 5-3 TestPage.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>
JSP Test Page
</TITLE>
</HEAD>
<BODY BGCOLOR="#FDF5E6">
<H2>URI: <%= request.getRequestURI() %></H2>
</BODY>
</HTML>
程序清单 5-4 web.xml (说明 JSP 页命名的摘录)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
" http://java.sun.com/dtd/web-app_2_3.dtd ">
<web-app>
<!-- ... -->
<servlet>
<servlet-name>PageName</servlet-name>
<jsp-file>/TestPage.jsp</jsp-file>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name> PageName </servlet-name>
<url-pattern>/UrlTest2/*</url-pattern>
</servlet-mapping>
<!-- ... -->
</web-app>
4 禁止激活器 servlet
对 servlet 或 JSP 页面建立定制 URL 的一个原因是,这样做可以注册从 init ( servlet )或 jspInit ( JSP 页面)方法中读取得初始化参数。但是,初始化参数只在是利用定制 URL 模式或注册名访问 servlet 或 JSP 页面时可以使用,用缺省 URL http://host/webAppPrefix/servlet/ServletName 访问时不能使用。因此,你可能会希望关闭缺省 URL ,这样就不会有人意外地调用初始化 servlet 了。这个过程有时称为禁止激活器 servlet ,因为多数服务器具有一个用缺省的 servlet URL 注册的标准 servlet ,并激活缺省的 URL 应用的实际 servlet 。
有两种禁止此缺省 URL 的主要方法:
l 在每个 Web 应用中重新映射 /servlet/ 模式。
l 全局关闭激活器 servlet 。
重要的是应该注意到,虽然重新映射每个 Web 应用中的 /servlet/ 模式比彻底禁止激活 servlet 所做的工作更多,但重新映射可以用一种完全可移植的方式来完成。相反,全局禁止激活器 servlet 完全是针对具体机器的,事实上有的服务器(如 ServletExec )没有这样的选择。下面的讨论对每个 Web 应用重新映射 /servlet/ URL 模式的策略。后面提供在 Tomcat 中全局禁止激活器 servlet 的详细内容。
4.1 重新映射 /servlet/URL 模式
在一个特定的 Web 应用中禁止以 http://host/webAppPrefix/servlet/ 开始的 URL 的处理非常简单。所需做的事情就是建立一个错误消息 servlet ,并使用前一节讨论的 url-pattern 元素将所有匹配请求转向该 servlet 。只要简单地使用:
<url-pattern>/servlet/*</url-pattern>
作为 servlet-mapping 元素中的模式即可。
例如,程序清单 5-5 给出了将 SorryServlet servlet (程序清单 5-6 )与所有以 http://host/webAppPrefix/servlet/ 开头的 URL 相关联的部署描述符文件的一部分。
程序清单 5-5 web.xml (说明 JSP 页命名的摘录)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
" http://java.sun.com/dtd/web-app_2_3.dtd ">
<web-app>
<!-- ... -->
<servlet>
<servlet-name>Sorry</servlet-name>
<servlet-class>moreservlets.SorryServlet</servlet-class>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name> Sorry </servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
<!-- ... -->
</web-app>
程序清单 5-6 SorryServlet.java
package moreservlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/** Simple servlet used to give error messages to
* users who try to access default servlet URLs
* (i.e., http://host/webAppPrefix/servlet/ServletName )
* in Web applications that have disabled this
* behavior.
* <P>
* Taken from More Servlets and JavaServer Pages
* from Prentice Hall and Sun Microsystems Press,
* http://www.moreservlets.com/.
* © 2002 Marty Hall; may be freely used or adapted.
*/
public class SorryServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "Invoker Servlet Disabled.";
out.println(ServletUtilities.headWithTitle(title) +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H2>" + title + "</H2>\n" +
"Sorry, access to servlets by means of\n" +
"URLs that begin with\n" +
" http://host/webAppPrefix/servlet/ \n" +
"has been disabled.\n" +
"</BODY></HTML>");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
4.2 全局禁止激活器: Tomcat
Tomcat 4 中用来关闭缺省 URL 的方法与 Tomcat 3 中所用的很不相同。下面介绍这两种方法:
1 .禁止激活器: Tomcat 4
Tomcat 4 用与前面相同的方法关闭激活器 servlet ,即利用 web.xml 中的 url-mapping 元素进行关闭。不同之处在于 Tomcat 使用了放在 install_dir/conf 中的一个服务器专用的全局 web.xml 文件,而前面使用的是存放在每个 Web 应用的 WEB-INF 目录中的标准 web.xml 文件。
因此,为了在 Tomcat 4 中关闭激活器 servlet ,只需在 install_dir/conf/web.xml 中简单地注释出 /servlet/* URL 映射项即可,如下所示:
<!--
<servlet-mapping>
<servlet-name>invoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
-->
再次提醒,应该注意这个项是位于存放在 install_dir/conf 的 Tomcat 专用的 web.xml 文件中的,此文件不是存放在每个 Web 应用的 WEB-INF 目录中的标准 web.xml 。
2 .禁止激活器: Tomcat3
在 Apache Tomcat 的版本 3 中,通过在 install_dir/conf/server.xml 中注释出 InvokerInterceptor 项全局禁止缺省 servlet URL 。例如,下面是禁止使用缺省 servlet URL 的 server.xml 文件的一部分。
<!--
<RequsetInterceptor
className="org.apache.tomcat.request.InvokerInterceptor"
debug="0" prefix="/servlet/" />
-->
5 初始化和预装载 servlet 与 JSP 页面
这里讨论控制 servlet 和 JSP 页面的启动行为的方法。特别是,说明了怎样分配初始化参数以及怎样更改服务器生存期中装载 servlet 和 JSP 页面