﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-JAVA流通桥-文章分类-servlet文章</title><link>http://www.blogjava.net/zhuyan/category/25113.html</link><description>JAVA启发者</description><language>zh-cn</language><lastBuildDate>Mon, 20 Aug 2007 18:42:08 GMT</lastBuildDate><pubDate>Mon, 20 Aug 2007 18:42:08 GMT</pubDate><ttl>60</ttl><item><title>Servlet2.3中文文档(第11,12,13章)</title><link>http://www.blogjava.net/zhuyan/articles/138198.html</link><dc:creator>朱岩</dc:creator><author>朱岩</author><pubDate>Mon, 20 Aug 2007 09:52:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyan/articles/138198.html</guid><wfw:comment>http://www.blogjava.net/zhuyan/comments/138198.html</wfw:comment><comments>http://www.blogjava.net/zhuyan/articles/138198.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyan/comments/commentRss/138198.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyan/services/trackbacks/138198.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第十一章 请求到servlet的映射<br>11.1 URI的使用<br>web容器根据客户端的请求决定要调用的资源。<br>URL路径映射规则是第一个匹配成功就不再匹配了。<br>1）引擎将尽力为每一个请求一个servlet的路径匹配一个servlet<br>2）引擎将递归的匹配最长的路径前缀（在一个目录树中）<br>3）如果在URL路径中的最后一节有扩展名（例如：.jsp），则servlet引擎将会匹配一个适当的servlet获<br>取请求对象<br>4）如果没有一个servlet能够匹配请求，引擎将用一个适当的资源来处理该请求。如：在应用中配置了<br>默认的servlet，就会被用来处理匹配不到资源的请求。<br>11.2 匹配规则<br>在web应用描述文件中，匹配的定义如下：<br>.以'/'开始，以'/*'为结尾的字符串,用作路径匹配<br>.以'*.'开始的字符串，用作扩展名匹配<br>.包含'/'字符串，定义一个默认的servlet。如匹配的servlet路径是请求URI路径的最小上下文路径，路经<br>的info为空。<br>.其它的字符串用作精确的匹配。<br>11.2.1 绝对匹配<br>servlet引擎能够匹配任何精确的资源，如后缀为*.jsp的匹配，引擎中有JSP引擎的话，就会把所有的JSP<br>页面和与之对象的资源相匹配。<br>11.2.2 匹配的例子：<br>path pattern servlet<br>/foo/bar/* servlet1<br>/baz/* servlet2<br>/catalog servlet3<br>*.bop servlet4<br>incoming path servlet handling request<br>/foo/bar/index.html servlet1<br>/foo/bar/index.bop servlet1<br>/baz servlet2<br>/baz/index.html servlet2<br>/catalog servlet3<br>/catalog/racecar.bop servlet4<br>/index.bop servlet4<br>第十二章 安全<br>12.1介绍<br>web应用的资源能够被很多的用户访问，这些资源经常没有保护的暴露在网络中，因此一个稳定的web<br>应用需要一个安全的环境。<br>提高安全性有以下的几个方面：<br>.认证：访问一个实例前需要一个特殊的ID进行授权认证后才能访问该实例<br>.资源的访问控制：一些机密资源或局部资源只限制给某些用户或程序使用。<br>.数据完整性：在传输过程中数据不能被意外的改变。<br>.机密性：确定信息只能被授权过的用户使用。<br>12.2 公共安全<br>安全性声明是指表明应用是有安全结构的；包括权限、访问控制、认证。在web应用中部署描述是安全<br>声明的主要工具。<br>开发者应该为应用运行时配一个逻辑安全策略，在运行时中，servlet引擎用这个安全策略去验证授权请<br>求。<br>安全模块应该适用web应用的静态内容，当servlet用RequestDispatcher调用一个静态资源或servlet用<br>forward或include,时安全模块不适用。<br>12.3 程序级安全<br>当应用的安全模块不能充分的表明安全时程序安全就可以被使用。<br>程序安全有以下部分组成：<br>HttpServletRequest接口：<br>.getRemoteUser<br>.isUserInRole<br>.getUserPrincipal<br>getRemoteUser方法返回客户端用户的名称，用于授权。<br>isUserInRole方法判断远程用户是否在一个安全的角色内。<br>getUserPrincipal方法返回一个java.security.Principal对象，表明当前用户的主要名称。这个API允许<br>servlet根据这个信息处理一些业务逻辑。<br>如果用户没有授权，getRemoteUser返回null，isUserInRole返回false，getUserPrincipal返回null。<br>isUserInRole以一个role-name为参数。一个security-role-ref元素为在部署描述文件中定义，role-name<br>子元素包含角色名称。Security-role包含一个子元素role-link,role-link的value值是客户端用户将匹配的<br>安全角色。当用isUserInRole时引擎将调用security-role-ref到security-role的匹配。<br>举个例子：<br>&lt;security-role-ref&gt;<br>&lt;role-name&gt;FOO&lt;/role-name&gt;<br>&lt;role-link&gt;manager&lt;/role-link&gt;<br>&lt;/security-role-ref&gt;<br>当一个用户属于&#8220;manager&#8221;角色是调用isUsesrInRole("FOO")返回true<br>如果匹配一个security-role元素的security-role-ref没有被定义，引擎必须找出一个与security-role<br>列表不同的roel-name元素作为web应用默认的安全角色。但默认的安全角色限制了变换角色名<br>称不需要重新编译的机动性。<br>12.4 角色<br>一个安全角色是一组用户的逻辑名称。当应用发布时，角色就部署在web应用的运行时环境中<br>了。在基于安全属性的请求到来时，servlet引擎就会执行公共安全或程序级安全。安全请求在以<br>下的一些情况中会产生：<br>1）开发者给用户群配置了一个安全角色。<br>2）开发者把一个安全角色配置给一个安全域中的一个主要名称。<br>12.5 验证<br>web客户端可以用以下的一些机制验证用户：<br>.HTTP Basic Authentication<br>.HTTP Digest Authentication<br>.HTTPS Client Authentication<br>.Form Based Authentication<br>12.5.1 HTTP Basic Authentication<br>HTTP Basic Authentication是基于用户名和密码的验证机制，是在HTTP/1.0规范中定义的。web<br>服务要求客户端验证用户，web服务用一个realm字符串作为请求的一部分，用户通过这个realm<br>字符串被验证。realm字符串不会和任何安全域相关联。客户端获得用户名称和密码发送到服务<br>端。然后服务端用一个特殊的realm去验证该用户。<br>Basic Authentication 不是安全的验证协议。用户的密码是用base64编码的，服务端是不能够识<br>别的。一些附加的安全措施可以被使用，这些协议有：HTTPS安全传输协议或网络安全标准（如<br>IPSEC协议、VPN策略）。<br>12.5.2 HTTP Digest Authentication<br>和HTTP Basic Authentication一样，HTTP Digest Authentication 也是验证用户名和密码的。然而<br>这种验证是把密码加密传输的，要比Basic Authentication的base64编码要安全的多。Digest<br>Authentication 没有被广泛的运用，建议servlet引擎支持这种验证，但不是必须的。<br>12.5.3 Form Based Authentication<br>web应用部署描述文件包含登陆表单和错误页面。登陆表单必须包含用户名和用户密码字段，这<br>两个字段必须以j_username和j_password命名。当一个用户要访问一个被保护的资源时，引擎就<br>会验证该用户信息，如果该用户验证通过就会调用保护的资源，如果没有验证通过，以下的步骤<br>就会发生：<br>1）登陆表单被送到客户端，启动这个验证的URL路径将被引擎保存。<br>2）用户被要求填写用户名和密码<br>3）客户端重新post表单到服务端<br>4）引擎尝试着重新去验证该用户的信息<br>5）如果验证有失败，响应被设置为401的错误页面将被返回<br>6）如果验证成功，如果该访问的资源在一个授权角色中，将进一步验证。<br>7）如果用户是授权用户，客户端将用保存的URL路径重新定向到访问的资源。<br>发送到验证失败的用户的错误页面包含了失败的信息。<br>Form Based Authentication 和 Basic Authentication 有一样的弊端，密码是用简单的文本传输<br>的，不能够被服务端验证。附加的一些协议可以增强这部分功能。如HTTPS传输协议，或网路安<br>全标准（如IPSEC协议或VPN策略）。<br>12.5.3.1 登陆表单的一些注意事项<br>登陆的表单和跟踪session的URL实现上是有限制的。<br>登陆表单只能在cookies或SSL跟踪session的方式下才能使用。<br>登陆表单要进行验证的话，表单的action就必须为j_security_check。这个约束使得登陆表单访问<br>的资源没有问题，也避免了把表单外的字段提交进请求中。<br>在HTML页面中登陆表单的一个例子如下：<br>&lt;form method="POST" action="j_security_check" &gt;<br>&lt;input type="text" name="j_username"&gt;<br>&lt;input type="password" name="j_password"&gt;<br>&lt;/form&gt;<br>当登陆表单因为HTTP请求被调用时，原始的请求参数必须被引擎存储，在验证成功后重新定向<br>请求的资源。<br>如果用登陆表单的用户被验证通过，创建了一个session,当session超时或调用了失效方法，使得<br>登陆者推出了。后续来的请求就必须重新对用户进行验证。<br>12.5.4 HTTPS Client Authentication<br>用HTTPS验证用户是很强的验证机制。这个验证需要用户拥有一个公共钥匙（PKC）。servlet引<br>擎不需要支持HTTPS协议。<br>12.6 验证信息的跟踪<br>基本的身份验证实在运行时环境中进行的：<br>1）确认一个登陆验证机制或策略已经配置在web应用中。<br>2）把需验证的信息发往一个容器中的所有应用。<br>3）当一个安全域被删除时，用户的请求就需要重新验证。<br></p>
<div><strong><font size=4>第十三章 部署描述文件</font></strong></div>
<div>13.1 部署描述元素</div>
<div align=left>部署描述文件中的所有元素都要被所有的<span>servlet引擎支持。配置类型有下面的几种：</span></div>
<div align=left>.ServletContext Init Parameteres</div>
<div align=left>.Session Configuration</div>
<div align=left>.Servlet Declaration</div>
<div align=left>.Servlet Mapping</div>
<div align=left>.Application Lifecycle Listener classes</div>
<div align=left>.Filter Dfinitions and Filter Mappings</div>
<div align=left>.MIME Type Mappings</div>
<div align=left>.Error Pages</div>
<div align=left>当<span>servlet 引擎是实现了J2EE规范的一部分的时候，安全信息才有必要在部署描述文件中定义。</span></div>
<div align=left>部署描述文件不光光只支持<span>servlet规范，在部署描述文件为了适应web应用的需求增加了其他的部属描述元素。如：</span></div>
<div align=left>.taglib</div>
<div align=left>.用于查找<span>JNDI对象的一些元素（env-entry,ejb-ref,ejb-local-ref,resource-ref,resource-env-ref）</span></div>
<div align=left>&nbsp;</div>
<div>13.2 处理部属描述文件的规则</div>
<div align=left>本节主要讲一下<span>web容器访问部属描述文件的几种规则。</span></div>
<div align=left>.web容器应该忽略部属描述文件中数据的开始空字符和最后的空字符。</div>
<div align=left>.web容器应该有一个广泛的选项用户检查<span>web应用的有效性。如检查web应用是否包含部署描述文件，部属描述文件结构是否正确。部署描述中应该有语义检查，如：安全规则有同样的名字，应该报错等等。</span></div>
<div align=left>.部署描述中的<span>URI是假定在URL解码表单中的</span></div>
<div align=left>.引擎必须正确解释部属文件中的路径，如：路径<span>'/a/../b'必须解释为'/b'，因为路径是以'..'开始的路径在部署描述中是无效的。</span></div>
<div align=left>.调用资源的<span>URI与WAR的根目录关联，以&#8216;/&#8217;开头</span></div>
<div align=left>.在一个元素中，如果它的显示值是一个列表，则这个列表将可能会报错</div>
<div>13.2.1 DOCTYPE</div>
<div align=left>所有<span>2.3版本的部属描述文件的DOCTYPE必须是：</span></div>
<div align=left>&lt;!DOCTYPE web-app PUBLIC "-//sun Microsystems, inc.//DTD Web Application 2.3//EN" "<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><u><font color=#0000ff>http://java.sun.com/dtd/web-app_2_3.dtd</font></u></a>"&gt;</div>
<div>13.3 DTD</div>
<div align=left>web应用的部署描述文件<span>DTD如下：</span></div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;web-app 元素是部署描述的根元素</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT web-app(icon?,display-name?,description?,distributable?,context-param*,filter*,filter-mapping*,listener*,servlet*,servlet-mapping*，<span>session-config?,mime-mapping*,welcome-file-list?,error-page*,taglib*,resource-env-ref*,resource-ref*,security-constraint*,login-config?,security-role*,env-entry*,ejb-ref*,ejb-local-ref*)&gt;</span></div>
<div align=left>&lt;!--</div>
<div align=left>Auth-constraint 元素定义了可以访问资源列表的用户角色。<span>Role-name可以作为security-role元素的子元素出现也可以以role-name"*"出现表示所有的角色，如果*和role-name都出现了，引擎将解释这个资源可以被所有角色使用。如果没有定义角色，用户就不能够访问定义的资源。</span></div>
<div align=left>Used in :security-constraint</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT auth-constraint (description?,role-name*)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>Auth-method 元素是配置<span>web应用的安全机制的，是访问被保护资源的先决条件。用户必须用这个验证机制验证。这个元素Value值有&#8220;BASIC&#8221;,&#8220;DIGEST&#8221;,&#8220;FORM&#8221;或&#8220;CLIENT-CERT&#8221;</span></div>
<div align=left>Userd in : login-config</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT auth-method(#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>Context-param元素包含了<span>servlet context初始化的参数</span></div>
<div align=left>Used in :web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT context-param(param-name,param-value,description?)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>description元素用于对父元素进行说明，<span>description元素可以包含任何说明信息。当父元素被工具访问时这些说明就会显示。</span></div>
<div align=left>Used in :auth-contraint,context-param,ejb-local-ref,ejb-ref,env-entry,filter,init-param,resource-env-ref,resource-ref,ren-as,security-role,security-role-ref,servlet,user-data-constraint,web-app,web-resource-collection</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT description(#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>Display-name元素是一个简称，被调用的工具显示，这个简称不必是唯一的</div>
<div align=left>Used in: filter,security-constraint,sevlet,web-app</div>
<div align=left>例如：</div>
<div align=left>&lt;display-name&gt;Employee self Service &lt;/display-name&gt;</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT display-name(#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>Distributable 元素<span>,这个元素出现在部署描述中，说明该应用可以部署在分布式servlet引擎中。</span></div>
<div align=left>Used in :web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT distributable EMPTY&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>Ejb-link 元素用在<span>ejb-ref 或ejb-local-ref元素中，去指定EJB关联的一个enterprise bean.</span></div>
<div align=left>Ejb-link中的名字是一个关联着<span>enterprise bean的路径 或者是目标bean+一个以&#8220;#&#8221;开头的路径。一个ejb-name可以对应多个enterprise beans。</span></div>
<div align=left>Used in : ejb-local-ref,ejb-ref</div>
<div align=left>例如：</div>
<div align=left>&lt;ejb-link&gt;EmployeeRecord&lt;/ejb-link&gt;</div>
<div align=left>&lt;ejb-link&gt;../products/product.jar#ProductEJB&lt;/ejb-link&gt;</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT ejb-link (#PCDAATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;ejb-local-ref 元素用于描述本地<span>enterprise bean的home接口，描述由下面的部分组成：</span></div>
<div style="MARGIN-LEFT: 36pt" align=left>一个可选的描述</div>
<div style="MARGIN-LEFT: 36pt" align=left>与<span>enterprise bean 相关的EJB名称</span></div>
<div style="MARGIN-LEFT: 36pt" align=left>Enterprise bean 的类型</div>
<div style="MARGIN-LEFT: 36pt" align=left>Enterprise bean 的本地接口</div>
<div style="MARGIN-LEFT: 36pt" align=left>可选的<span>ejb-link信息</span></div>
<div align=left>Used in：<span> web-app</span></div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT ejb-local-ref (description？，<span>ejb-ref-name,ejb-ref-type,local-home,local,ejb-link?)&gt;</span></div>
<div align=left>&lt;!--</div>
<div align=left>Ejb-ref 元素用于描述<span>enterprise bean的home接口。描述由下面组成：</span></div>
<div style="MARGIN-LEFT: 36pt" align=left>一个可选描述</div>
<div style="MARGIN-LEFT: 36pt" align=left>与<span>enterprise bean 相关的EJB名称</span></div>
<div style="MARGIN-LEFT: 36pt" align=left>Enterprise bean 的类型</div>
<div style="MARGIN-LEFT: 36pt" align=left>Enterprise bean 的本地接口</div>
<div style="MARGIN-LEFT: 36pt" align=left>可选的<span>ejb-link信息</span></div>
<div align=left>Used in：<span>web-app</span></div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT ejb-ref(description？，<span>ejb-ref-name,ejb-ref,type,home,remote,ejb-link?)&gt;</span></div>
<div align=left>&lt;!--</div>
<div align=left>Ejb-ref-name 元素包含一个<span>EJB的名字，这个名字必须是唯一的；这个EJB是web应用环境和关联的java:comp/env context的入口。建议名字以&#8220;ejb/&#8221;开头。</span></div>
<div align=left>Used in : ejb-local-ref,ejb-ref</div>
<div align=left>例如：</div>
<div align=left>&lt;ejb-ref-name&gt;ejb/Payroll&lt;/ejb-ref-name&gt;</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT ejb-ref-name(#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>Ejb-ref-type 元素包含<span>enterprise bean的类型。Ejb-ref-type元素必须是下面的一种：</span></div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;ejb-ref-type&gt;Entity&lt;/ejb-ref-type&gt;</div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;ejb-ref-type&gt;Session&lt;/ejb-ref-type&gt;</div>
<div align=left>Used in :ejb-local-ref,ejb-ref</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT ejb-ref-type(#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>Env-entry 元素包含了<span>web应用的环境入口的描述。描述包含一个可选的描述，一个环境入口的名称，一个可选的value，如果value没有被指定，在部署中必须提供。</span></div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT env-entry (description?,env-entry-name,env-entry-value?,env-entry-type)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;env-entry-name元素包含了<span>web应用环境入口的名称，这个名称是一个java:comp/env context关联的JNDI名称。名字必须是唯一的。</span></div>
<div align=left>例如：</div>
<div align=left>&lt;env-entry-name&gt;minAmount&lt;/env-entry-name&gt;</div>
<div align=left>Used in: env-entry</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT env-entry-name(#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>Env-entry-type 元素包含环境入口值的<span>fully-qualified java类型，这是web应用程序期望有的。</span></div>
<div align=left>Env-enry-type合法的类型如下：</div>
<div style="MARGIN-LEFT: 36pt" align=left>Java.lang.Boolean</div>
<div style="MARGIN-LEFT: 36pt" align=left>Java.lang.Byte</div>
<div style="MARGIN-LEFT: 36pt" align=left>Java.lang.Character</div>
<div style="MARGIN-LEFT: 36pt" align=left>Java.lang.String</div>
<div style="MARGIN-LEFT: 36pt" align=left>Java.lang.Short</div>
<div style="MARGIN-LEFT: 36pt" align=left>Java.lang.Integer</div>
<div style="MARGIN-LEFT: 36pt" align=left>Java.lang.Long</div>
<div style="MARGIN-LEFT: 36pt" align=left>Java.lang.Float</div>
<div style="MARGIN-LEFT: 36pt" align=left>Java.lang.Double</div>
<div align=left>Used in : env-entry</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT env-entry-type(#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>Env-entry-value元素包含了<span>web应用环境入口的值，值必须是一个字符串。</span></div>
<div align=left>例如：</div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;env-entry-value&gt;100.00&lt;/env-entry-value&gt;</div>
<div align=left>Used in : env-entry</div>
<div align=left>&lt;!ELEMENT env-entry-value(#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>Error-code元素包含<span>HTTP的一个错误代码，如：404</span></div>
<div align=left>Used in : error-page</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT error-code(#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;error-page 元素包含一个错误代码映射或错误类型资源的一个路径</div>
<div align=left>Used in : web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT error-page((error-code | exception-type),location)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;exception-type 包含一个<span>java exception 类型的类名称</span></div>
<div align=left>Used in : error-page</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT exception-type(#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;extension元素包含一个扩展名。如&#8220;<span>txt&#8221;</span></div>
<div align=left>Used in : mine-mapping</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT extension (#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;filter被<span>filter-mapping中的一个servlet或一个URL通过filter-name映射。filter在运行时能够通过FilterConfig接口访问初始化的参数。</span></div>
<div align=left>Used in : web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT filter (icon?,filter-name,display-name?,description?,filter-class,init-param*)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;filter-class元素指明<span>filter类.</span></div>
<div align=left>Used in :filter</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT filtere-class(#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;引擎用<span>filter-mapping去匹配请求的URI以及匹配的顺序，引擎在把匹配的URI匹配一个servlet。</span></div>
<div align=left>Used in : web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT filter-mapping (Filter-name,(url-pattern | servlet-name))&gt; </div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;filtere-name元素表明了一个<span>filter的逻辑名称用于匹配用的。逻辑名称必须唯一</span></div>
<div align=left>Used in : filter,filere-mapping</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT filter-name (#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;form-error-page元素定义了当登陆失败是调用的页面。这个路径以&#8220;<span>/&#8221;开始</span></div>
<div align=left>Used in: form-login-config</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT form-error-page (#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;form-login-config元素指定了登陆的错误页面，如果<span>form不需要验证，这个元素将被忽略。</span></div>
<div align=left>Used in : login-config</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT form-login-cofig (form-login-page,form-error-page)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;form-login-page 元素定义了登陆的页面。路径以&#8220;<span>/&#8221;开头</span></div>
<div align=left>&nbsp;used in :form-login-config</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT form-login-page (#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;home元素包含了<span>enterprise bean的home接口的名称</span></div>
<div align=left>Used in :ejb-ref</div>
<div align=left>例如：</div>
<div align=left>&lt;home&gt;com.aardvark.payroll.PayrollHome&lt;/home&gt;</div>
<div align=left>&lt;!ELEMENT home (#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;http-method 包含了<span>HTTP 方法(GET | POST |...)</span></div>
<div align=left>Used in:web-resource-collection</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT http-method (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;icon 元素包含<span>small-icon 和large-icon元素，指明一个gif或jpeg的图标名称</span></div>
<div align=left>Used in : filter,servlet,web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT icon (small-icon?,large-icon?)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;init-param元素包含了<span>name/value的servlet的初始化参数</span></div>
<div align=left>Used in : filter,servlet</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMETN init-param (param-name,param-value,description？<span>)&gt;</span></div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;jsp-file 元素 包含了一个以&#8220;<span>/&#8221;开头JSP文件的全名。</span></div>
<div align=left>Used in : servlet</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT jsp-file (#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;large-icon 元素包含一个<span>32*32的图标文件名称。图片可以是jpeg或gif。</span></div>
<div align=left>&nbsp;used in ：<span>icon</span></div>
<div align=left>例如：</div>
<div align=left>&lt;large-icon&gt;employee-service-icon32*32.jsp&lt;/large-icon&gt;</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT large-icon (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;listener 元素对应着<span>listener bean</span></div>
<div align=left>Used in : web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT listener (listener-class)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;listener-class 元素，元素值是监听类的类名。</div>
<div align=left>Used in : listener</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT listener-class (#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;load-on-startup 元素指明了这个<span>servlet在web启动时是否必须装入（调用servlet的init()方法）。这个内容是可选的，但有值时必须是个整数，如果是负数，引擎可以选择在任何时候装载该servlet，如果是整数或0，引擎就必须在web应用启动时装入该servlet。数字越小越被优先装入。如果值一样，引擎可以自由选择装入的顺序。</span></div>
<div align=left>Used in : servlet</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT load-on-startup (#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;local元素包含了<span>enterprise bean的local接口</span></div>
<div align=left>Used in : ejb-local-ref</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT local (#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;local-home元素包含了<span>enterprise bean的本地home接口</span></div>
<div align=left>Used in : ejb-local-ref</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT local-home (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;location 元素包含与<span>web应用根目录关联的资源，值必须以&#8216;/&#8217;开头</span></div>
<div align=left>Used in : error-page</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT location (#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;login-config 元素用于配置验证的方法的。</div>
<div align=left>Used in :web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT login-conifg (auth-method?,realm-name?,form-login-config?)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;mime-mapping 元素定义了扩展名和<span>mime类型的映射关系。</span></div>
<div align=left>Used in :web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT mime-mapping (extension,mime-type)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;mime-type 元素包含了<span>mime类型，如&#8220;text/plain&#8221;</span></div>
<div align=left>Used in : mime-mapping</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT mime-type (#PCDATA)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;param-name 元素包含参数的名称，参数名必须唯一。</div>
<div align=left>Used in : context-param,init-param</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT param-name (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;param-value元素包含了参数的值</div>
<div align=left>Used in : context-param,init-param</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT param-value (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;realm-name 元素用于<span>HTTP Basic 验证中</span></div>
<div align=left>Used in : login-config</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT realm-name (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;remote 元素包含了<span>enterprise bean 的remote接口</span></div>
<div align=left>Used in : ejb-ref</div>
<div align=left>例如：</div>
<div align=left>&nbsp;&lt;remote&gt;com.wombat.empl.EmployeeService&lt;/remote&gt;</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT remote (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;res-auth 元素表明是<span>web应用代码控制资源，还是引擎控制资源。该元素的值只能是以下的一种</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;res-auth&gt;Application&lt;/res-auth&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;res-auth&gt;Container&lt;/res-auth&gt;</span></div>
<div align=left>Used in : resource-ref</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT res-auth (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;res-ref-name 元素指明了资源管理器（连接工厂）的名称，这个名称是和<span>java:comp/env cocntext关联的JNDI名称。该名称必须是唯一的。</span></div>
<div align=left>Used in：<span>resource-ref</span></div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT res-ref-name (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;res-sharing-scope 元素表明了从资源管理器连接工厂获得的连接是否可以被共享。值必须是下面的一种：</div>
<div align=left>&nbsp;&lt;res-sharing-scope&gt;Shareable&lt;/res-sharing-scope&gt;</div>
<div align=left>&nbsp;&lt;res-sharing-scope&gt;Unshareable&lt;/res-sharing-scope&gt;</div>
<div align=left>默认的值是<span>Shareable</span></div>
<div align=left>Used in : resource-ref</div>
<div align=left>&lt;!ELEMENT ref-sharing-scope (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;res-type 元素描述了资源的数据类型。</div>
<div align=left>Used in : resource-ref</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT res-type (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;resource-env-ref 元素描述了与<span>web应用管理对象相关的资源。包含一个可选的描述，一个资源环境名称，一个环境资源类型。</span></div>
<div align=left>Used in :web-app</div>
<div align=left>例如：</div>
<div align=left>&lt;resource-env-ref&gt;</div>
<div align=left>&nbsp;&lt;resource-env-ref-name&gt;jms/StockQueue&lt;/resource-env-ref-name&gt;</div>
<div align=left>&nbsp;&lt;resource-env-type&gt;javax.jms/Queue&lt;/resource-env-ref-type&gt;</div>
<div align=left>&lt;/resource-env-ref&gt;</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT resource-env-ref (description?,resource-env-ref-name,resource-env-ref-type)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;resource-env-ref-name元素一定一个环境资源名称，这个名字是与<span>java:comp/env context关联的JNDI名称，必须以唯一的。</span></div>
<div align=left>Used in : resource-env-ref</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT resource-env-ref-name (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;resource-env-ref-type元素定义了环境资源的类型，是一个<span>java类或接口的全名。</span></div>
<div align=left>Used in: resource-env-ref</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT resource-env-ref-type (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left><span>&nbsp;&nbsp; resource-ref </span>元素包含<span>web应用涉及的外部资源的描述。它有一个可选的描述，一个资源管理连接工厂的名称，一个资源管理连接工厂的类型id，一个验证类型（Application 或 Container）,和一个可选的连接共享的选项（Shareale 或 Unshareable）</span></div>
<div align=left>Used in : web-app</div>
<div align=left>例如：</div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;resource-ref&gt;</div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;res-ref-name&gt;jdbc/EmployeeApppDB&lt;/res-ref-name&gt;</div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;</div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;res-auth&gt;Container&lt;/res-auth&gt;</div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;res-sharing-scope&gt;Shareable&lt;/res-sharing-scope&gt;</div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;/resource-ref&gt;</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT resource-ref (description?,res-ref-name,res-type,res-auth,res-sharing-scope?)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;role-link 元素是与安全角色相关的。<span>Role-link元素必须包含一个在security-role元素中定义的安全角色的名称。</span></div>
<div align=left>Used in: security-role-ref</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT role-link (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;role-name 元素包含一个安全角色的名称，名称必须遵守<span>NMTOKEN规则。</span></div>
<div align=left>Used in : auth-constraint,run-as,security-role,security-role-ref</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT role-name (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;run-as 元素包含一个可选的描述，和一个安全角色的名称。</div>
<div align=left>Used in : servlet</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT run-as (description?,role-name)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;security-constraint元素用于安全约束与一个或多个<span>web资源相关联。</span></div>
<div align=left>Used in :web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT security-constraint (display-name?,web-resource-collection+,auth-constraint?,user-data-constraint?)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;security-role元素包含安全角色的定义，它由一个可选的安全角色的描述，一个安全角色名称组成。</div>
<div align=left>Used in : web-app</div>
<div align=left>例如：</div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;security-role&gt;</div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;description&gt;</div>
<div style="MARGIN-LEFT: 36pt" align=left><span>&nbsp;&nbsp; this role includes all employees who are authorized to access the employee service application.</span></div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;/description&gt;</div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;role-name&gt;employee&lt;/role-name&gt;</div>
<div style="MARGIN-LEFT: 36pt" align=left>&lt;/security-role&gt;</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT security-role (description?,role-name)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;security-role-ref 元素包含一个可选的描述，一个调用代码中的安全角色名称，一个可选的安全角色连接。如果安全角色没有被指定，开发者必须选择一个适当的安全角色。这个<span>role-name元素的值必须是EJBConteext.isCallerInRole(String roleName)或HttpServletRequest.isUserInRole(String role)中的参数。</span></div>
<div align=left>Used in :servlet</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT security-role-ref (description?,role-name,role-link?)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;servlet 元素包含一个<span>servlet的数据描述。如果load-on-startup元素中指定了一个jsp文件，该JSP将被装入。</span></div>
<div align=left>Used in : web-app</div>
<div align=left>&lt;!ELEMENT servlet (icon?,servlet-name,display-name?,description?,(servlet-class|jsp-file),init-param*,load-on-startup?,run-as?,security-role-ref*)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;servlet-class元素包含一个全名的<span>servlet类名称。</span></div>
<div align=left>Used in : servlet</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT servlet-class (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;servlet-mapping元素定义了一个<span>servlet和url的关联</span></div>
<div align=left>Used in : web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT servlet-mapping (servlet-name,url-pattern)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;servlet-name元素包含<span>servlet的名称，名称是唯一的。</span></div>
<div align=left>Used in : filter-mapping,servlet,servlet-mapping</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT servlet-name (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;session-config 元素定义了<span>session参数</span></div>
<div align=left>Used in : web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT session-config (session-timeout?)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;session-timeout 元素定义了一个默认的会话超时的时间，使用于<span>web应用中的所有会话。时间必须是用分钟的数值表示。</span></div>
<div align=left>如果<span>timeout是0或负数，引擎将确保会话永远不会超时。</span></div>
<div align=left>Used in : session-config</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT session-timeout (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;small-icon 元素包含一个<span>16*16图标文件的名称。</span></div>
<div align=left>Used in : icon</div>
<div align=left>例如：</div>
<div align=left>&nbsp;&lt;small-icon&gt;employee-service-icon16*16.jpg&lt;/small-icon&gt;</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT small-icon (#pCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&nbsp;taglib 元素用于描述<span>JSP tag 库。</span></div>
<div align=left>Used in : web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT taglib (taglib-uri,taglib-location)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;taglib-location 元素包含一个资源定位，为<span>tag库找到tag描述文件</span></div>
<div align=left>Used in:taglib</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT taglib-location (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;taglib-uri元素描述了一个<span>URI</span></div>
<div align=left>Used in: taglib</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT taglib-uri (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;transport-guarantee元素指定了客户端和服务端的通信关系，有<span>NONE，INTEGRAL,CONFIDENTIAL。NONE表示着应用不需要任何传输保障。INTEGRAL表示着在数据在客户端到服务端的过程中不能有任何改变。CONFIDENTIAL表示在传输过程中防止其他传输内容的干扰。在使用SSl时常用的就INTEGRAL或CONFIDENTIL。</span></div>
<div align=left>Used in : user-data-constraint</div>
<div align=left>&lt;!ELEMENT transport-guarantee (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;url-pattern 元素包含映射的<span>url。必须符合11.2章中servlet API描述的规则。</span></div>
<div align=left>Used in:filter-mapping,servlet-mapping,web-resource-collection</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT url-pattern (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;user-data-constraint元素用于表明数据在客户端到服务器端是怎么保护的。</div>
<div align=left>Used in :security-constraint</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT user-data-constraint (description?,transport-guarantee)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;web-resource-collection元素用于<span>web应用中安全限制的资源被那些方法使用，如果没有指定，就可以被web用的所有方法调用。</span></div>
<div align=left>Used in:security-constraint</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT web-resource-collection (web-resource-name,description?,url-pattern*,http-method*)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;web-resource-name 包含一个<span>web资源集合的名称</span></div>
<div align=left>Used in:web-resource-collection</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT web-resource-name (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;welcome-file元素包含了<span>web应用中默认的访问文件，如index.html</span></div>
<div align=left>Used in:welcome-file-list</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT welcome-file (#PCDATA)&gt;</div>
<div align=left>&nbsp;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;welcome-file-list包含<span>welcome-file的列表</span></div>
<div align=left>Used in:web-app</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ELEMENT welcome-file-list (welcome-file+)&gt;</div>
<div align=left>&lt;!--</div>
<div align=left>&nbsp;ID机制可以增加额外的部署信息，不允许加一个非标准的元素到标准的部署描述中</div>
<div align=left>--&gt;</div>
<div align=left>&lt;!ATTLIST auth-constraint id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST auth-method id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST context-param id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST description&nbsp;id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST display-name id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST ejb-link id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST ejb-local-ref id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST ejb-ref &nbsp;id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST ejb-ref-name id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST ejb-ref-type id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST env-entry id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST env-entry-name id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST env-entry-type id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST env-enry-value id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST error-code id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST error-page id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST exception-type id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST extension&nbsp;id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST filter id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST filter-class id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST filtere-mapping id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST filter-name id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST form-error-page id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST form-login-config id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST form-login-page id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST home id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST http-method id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST icon id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST init-param id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST jsp-file id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST large-icon id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST listener id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST listener-class id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST load-on-startup id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST local id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST local-home id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST location id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST login-config id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST mime-mapping id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST mime-type id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST param-name id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST param-value id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST realm-name id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST remote id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST res-auth id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST res-ref-name id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST res-sharing-scope id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST res-type id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST resource-env-ref id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST resource-env-ref-name id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST resource-env-ref-type id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST resource-ref id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST role-link id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST role-name id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST run-as id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST security-constraint id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST security-role id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST security-role-ref id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST sevlet id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST servlet-class id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST servlet-mapping id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST servlet-name id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST session-config id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST session-timeout id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST small-icon id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST taglib id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST taglib-location id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST taglib-uri id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST transport-guarantee id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST rul-pattern id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST user-data-constraint id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST web-app id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST web-resource-collection id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST web-resource-name id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST welcome-file id ID #IMPLIED&gt;</div>
<div align=left>&lt;!ATTLIST welcome-file-list id ID #IMPLIED&gt;</div>
<div align=left>&nbsp;</div>
<div>13.4 例子</div>
<div>13.4.1 基本的例子</div>
<div align=left>&lt;!DOCTYPE web-app PUBLIC "-//Sun Mmicrosystems, Inc.//DTD Web Application 2.3//EN" "<a href="http://java.sun.com/j2ee/dtds/web-app_2_3.dtd"><u><font color=#0000ff>http://java.sun.com/j2ee/dtds/web-app_2_3.dtd</font></u></a>"&gt;</div>
<div align=left>&lt;web-app&gt;</div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;display-name&gt;A Simple Application&lt;/display-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;context-param&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;Webmaster&lt;/param-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;webmaster@mycorp.com&lt;/param-value&gt;</span></div>
<div align=left>&nbsp;<span>&nbsp;&nbsp;&lt;/context-param&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;servlet&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;catalog&lt;/servlet-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;serrvlet-class&gt;com.mycorp.Catalogservlet&lt;/servlet-class&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;catalog&lt;/param-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;Spring&lt;/param-value&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;catalog&lt;/servlet-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/catalog/*&lt;/url-pattern&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;session-config&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;session-timeout&gt;30&lt;/session-timeout&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;/session-config&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;mime-mapping&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;extension&gt;pdf&lt;/extension&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;mime-type&gt;application/pdf&lt;/mime-type&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;/mime-mapping&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;welcome-file-list&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;welcome-file&gt;index.html&lt;/welcome-file&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;welcome-file&gt;index.htm&lt;/welcome-file&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;/welcome-file-list&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;error-page&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;error-code&gt;404&lt;/error-code&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;location&gt;/404.html&lt;/location&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;error-page&gt;</span></div>
<div align=left>&lt;/web-app&gt;</div>
<div align=left>&nbsp;</div>
<div>13.4.2 一个安全的例子</div>
<div align=left>&lt;!DOCTYPE web-app PUBLIC "-//Sun Mmicrosystems, Inc.//DTD Web Application 2.3//EN" "<a href="http://java.sun.com/j2ee/dtds/web-app_2_3.dtd"><u><font color=#0000ff>http://java.sun.com/j2ee/dtds/web-app_2_3.dtd</font></u></a>"&gt;</div>
<div align=left>&lt;web-app&gt;</div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;display-name&gt;A Secure Application&lt;/display-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;security-role&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;role-name&gt;manager&lt;/role-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;/security-role&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;servlet&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;catalog&lt;/servlet-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;com.mycorp.CatalogServlet&lt;/servlet-class&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;catalog&lt;/param-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;Spring&lt;/param-value&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;security-role-ref&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;role-name&gt;MGR&lt;/role-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- </span>在代码中用的角色名称<span>--&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;role-link&gt;manager&lt;/role-link&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/security-role-ref&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;catalog&lt;/servlet-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/catalog/*&lt;/url-pattern&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;security-constraint&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;web-resource-collection&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;web-resource-name&gt;SalesInfo&lt;/web-resource-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/salesinfo/*&lt;/url-pattern&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;http-method&gt;GET&lt;/http-method&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;http-method&gt;POST&lt;/http-method&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/web-resource-collection&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;auth-constraint&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;role-name&gt;manager&lt;/role-name&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/auth-constraint&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;user-data-constraint&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/user-data-constraint&gt;</span></div>
<div align=left><span>&nbsp;&nbsp;&nbsp; &lt;/security-constraint&gt;</span></div>
<div align=left>&lt;/web-app&gt;</div>
<div align=left>&nbsp;</div>
<div>结尾：</div>
<div align=left>servlet2.3到此就结束了，至于对接口类的解释。这里就不给与了。有兴趣的朋友可以<span>down一个servlet2.3的源码包自己研究研究。</span></div>
<img src ="http://www.blogjava.net/zhuyan/aggbug/138198.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyan/" target="_blank">朱岩</a> 2007-08-20 17:52 <a href="http://www.blogjava.net/zhuyan/articles/138198.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Servlet2.3中文文档(第8，9，10章)</title><link>http://www.blogjava.net/zhuyan/articles/138196.html</link><dc:creator>朱岩</dc:creator><author>朱岩</author><pubDate>Mon, 20 Aug 2007 09:43:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyan/articles/138196.html</guid><wfw:comment>http://www.blogjava.net/zhuyan/comments/138196.html</wfw:comment><comments>http://www.blogjava.net/zhuyan/articles/138196.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyan/comments/commentRss/138196.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyan/services/trackbacks/138196.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第八章 Dispatching Requests<br>当建立一个web应用时，把一个请求传给另一个servlet或在response中包含另一个servlet的输出是经常<br>使用的。RequestDispatcher接口就提供了一些方法。<br>8.1 获得RequestDispatcher<br>实现了接口RequesetDispatcher接口的对象可以在ServletContext的getRequestDispatcher或<br>getNamedDispatchcer方法得到。<br>getRequestDispatcher的参数是一个以根目录&#8216;/&#8217;开始的一个路径，该方法会查找路径下的servlet，并把<br>它封装成RequestDispatchcer对象返回。<br>getNamedDispatcher方法把一个ServletContext知道的servlet名字作为参数，如果找到servlet，该<br>servlet就被封装成RequestDispatcher对象返回，如果没有找到则返回null。<br>RequestDispatcher对象中使用相对路径也是可以的。在ServletRequest中提供了getRequestDispatcher<br>方法；这个方法和ServletContext中同名的方法功能类似。servlet引擎会用request的信息把相对路径转<br>化成完整路径的。如ServleltRequest.getRequestDispatcher("header.html")和ServletConext.<br>getRequestDispatcher("/garden/headere.html")是等效的。<br>8.1.1 在Request Dispatcher 路径中附加字符串<br>在ServletContext和ServletRequest创建RequestDispatcher方法中参数都可以带字符串如：<br>Context.getRequestDispatcher("/raisons.jsp?orderno=5");<br>8.2 Request Dispatcher的使用<br>对于使用Request Dispatcher 而言就是一个servlet调用include或forward方法，这些方法的参数是<br>Servlet接口传来的request和response对象实例。引擎必须确保调用Request Dispatcher的处理过程是在<br>同一个JVM的同一个线程中。<br>8.3 include 方法<br>RequestDispatcher接口的include方法可以在任何时候被调用；目标servlet可以包含所有外的request对<br>象，不过response对象的使用是有限制的：<br>response只能写信息到ServletOutputStream 或者Writer中，调用response对象的flushBuffer方法进行提<br>交。不能够设置头信息，任何方法都不会影响到response的头信息。<br>8.3.1 被包含的request参数<br>除了可以用getNamedDispatcher方法包含一个servlet外，以下的属性可以被设置：<br>Java.servlet.include.request_uri<br>Java.servlet.include.context_path<br>Java.servlet.include.servlet_path<br>Java.servlet.include.path_info<br>Java.servlet.include.query_string<br>用request对象的getAttribute方法可以获取被包含servlet的以上属性。<br>如果被包含的servlet能后通过getNamedDispatcher方法找到就不必设置以上属性了。<br>8.4 Forward 方法<br>RequestDispatcher接口中的forward方法，只有servlet没有提交响应到客户端时才可用；如果响应<br>buffer中有数据还没有提交，当调用forward方法中目标servlet的service方法前，buffer中的内容会被清<br>空；如果buffer中的数据提交了，则发生IllegalStateException错误。<br>request对象的路径必须放映获取RequestDispatcher对象的路径。<br>有个例外，如果RequestDispatcher是通过getNamedDispatcher方法得到的，request对象必须反映原始<br>request的路径。<br>在RequestDispatcher接口方法forward返回前，response的内容必须被提交，并由引擎关闭该servlet。<br>8.4.1 query String<br>在Request Dispatcher中创建的路径是可以带参数的。<br>8.5 错误<br>如果request Dispatcher的目标servlet抛出运行时错误或ServletException 或IOException，错误就会被<br>传给调用的servlet；在上传之到调用的servlet之前，所有其他的exception都应该包装成<br>ServletExceptions。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第九章 web 应用<br>一个web应用是一堆servlet，html页面，类和其他资源的集合。web应用可以被发布运行在很多服务提<br>供商的多种引擎下。<br>9.1 web服务器<br>在web服务中一个web应用的根目录是一个特殊的路径，例如：一个网站目录可以以<a href="http://www/">http://www</a>.<br>mycorp.com/登录，所有的请求都将以这个作为前缀发送到以这个前缀描述的servletContext环境中。<br>在任何时候一个web应用的实例只能运行在一个JVM中。<br>9.2 和servletContext的关系<br>servlet引擎会强迫web应用和ServletContext的通信，一个ServletContext对象提供了一个servlet使得该<br>应用可见。<br>9.3 web应用中的元素<br>一个web应用包含以下的元素：<br>.Servlets<br>.JSP<br>.Utility Classes<br>.Static documents(html,images,sounds,etc)<br>.Client side Java applets,beans,and classes<br>.Descriptive meta informateion<br>9.4 部署层次<br>这个协议定义了一个层次结构，用于部署和打包，这个结构存在于一个文件中。<br>9.5 目录结构<br>一个web应用存在一个目录层次结构。文件根目录是应用的一部分。例如：一个web应用的上下文路径<br>是/catalog，web应用的index.html文件就能被/catalog/index.html请求访问。URL和上下文路径的匹配<br>规则将在11章讨论。servlet引擎必须拒绝一个具有现在冲突的上下文路径的web应用，这种情况是有<br>的，如：两个web应用发布在同一个上下文路径中，或一个web应用的上下文路径是另一个web应用上<br>下文路径的子路径。<br>有一个特殊的目录（&#8220;WEB-INF&#8221;）在应用中存在，这个目录包含所有与应用相关，又不在根目录中的事<br>物。可以直接被引擎提供给客户端的文件不放在WEB-INF中，但WEB-INF目录对于调用ServletContext<br>的getResource和getResourceAsStream方法的servlet 代码是有效的。如果开发者想用servlet代码调用<br>一个不希望暴露给客户端的一个配置信息，就可以把这个配置信息放在WEB-INF目录下。请求都是和资<br>源相匹配的；敏感的匹配如客户端的请求是&#8220;/WEB-INF/foo&#8221;和&#8220;/Web-iNf/foo&#8221;，但不应该把定位于/<br>WEB-INF下的内容作为结果返回。<br>WEB-INF目录下的内容有：<br>./WEB-INF/web.xml 部署描述文件<br>./WEB-INF/classes/ 存放servlet class<br>./WEB-INF/lib/*.jar 是jar包的目录<br>应用的classloader先load WEB-INF/classes目录下的class后load WEB-INF/lib目录下的jar包<br>9.5.1 目录结构的一个例子<br>一个简单web应用的目录结构：<br>/index.html<br>/howto.jsp<br>/images/banner.gif<br>/images/jumping.gif<br>/WEB-INF/web.xml<br>/WEB-INF/lib/jspbean.jar<br>/WEB-INF/classes/com/mycorp/servlets/MyServlet.class<br>/WEB-INF/classes/com/util/MyUtils.class<br>9.6 web应用的存档文件<br>一个web应用可以被java打包工具打包成war文件，当被打包后包中就会有一个额外META-INF目录，该<br>目录下存放了打包工具的一些信息。<br>9.7 web应用部署描述<br>下面是web应用部署描述中的配置类型：<br>.ServletContext Init Parameters<br>.Session Configuration<br>.Servlet / JSP Definitions<br>.Servlet / JSP Mappings<br>.MIME Type Mappings<br>.Welcome File list<br>.Error Pages<br>.Security<br>9.7.1 可靠的扩展<br>web容器须提供一种机制使得web应用知道jar文件中包含的有用资源或代码。<br>引擎因该提供编辑、配置库文件的程序。<br>在WAR中提供一个MANIFEST.MF文件，描述扩展名列表是比较好的。标准的JAR是应该有的，这个文件<br>描述的扩展名应该遵循<a href="http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html">Http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html</a>中的规<br>定。web容器应该能够识别WEB-INF/lib文件夹中的任何文件的扩展名，如果不能够识别就应该拒绝该<br>应用程序，并报出错误。<br>9.7.2 web应用的classloader<br>引擎用于装载war中的servlet的装载器必须能够让开发者装载jar库中的任何资源。但装载的资源禁止覆<br>盖j2se或servlet API中的类；通常建议的做法是装载器不允许war中的servlet去访问web引擎中的类。<br>还有一个被推荐的做法是实现应用类装载器，war中被装载的类或资源就会被放到container-wide JAR库<br>的特定类或资源中。<br>9.8 替换web应用<br>一个服务器可能会在不重新启动引擎的情况下用一个新版本的应用替换原有的应用。当一个应用被替换<br>时，引擎应提供一个robust方法去保存该应用中的session<br>9.9 错误句柄<br>9.9.1 request Attributes<br>web应用必须列出在使用中资源发生的错误，这些资源在部署描述中都有定义。<br>如果错误在一个servlet或一个jsp页面中发生，则在第9.1章中的如下的请求属性就会被设置：<br>Request Attributes Type<br>Javax.servlet.error.status_code java.lang.Integer<br>Javax.servlet.error.exception_type java.lang.Class<br>Javax.servlet.error.message java.lang.String<br>Javax.servlet.error.exception java.lang.Throwable<br>Javax.servlet.error.request_uri java.lang.String<br>Javax.servlet.error.servlet_name java.lang.String<br>这些属性允许这个servlet根据这些状态码、错误类型、错误信息、被抛出的错误对象、错误产生的<br>servlet被访问的URI（可以用getRequestURI得到）、或错误产生的servlet的逻辑名称产生特殊的内<br>容。<br>在2.3版本中错误类型和错误信息属性是多余的，他们被保留只是为了向下兼容以前的版本。<br>9.9.2 错误页面<br>当一个servlet产生错误时，开发者可以订制错误内容返回给客户端。部署描述文件定义了一个错误页面<br>列表。servlet在response中设置错误状态码或产生的异常或错误被引擎支持时，引擎就会从部署描述文<br>件中调用相应的配置的错误资源。<br>如果一个错误码被设置在了response中，引擎在部署描述文件的错误页面列表中用status-code方式匹配<br>对应的资源，如果找到就调用本地的资源。<br>在一个请求被处理的过程中servlet可以抛出以下的异常：<br>.runtime exceptions or errors<br>.ServletExceptions or subclasses thereof<br>.IOException or subclasses thereof<br>web应用可以用exception-type元素来描述错误页面，在这种情况下引擎会通过比较用exception-type元<br>素定义的error-page列表中的异常来匹配产生的异常。匹配的结果是返回定义的与错误匹配的本地资<br>源。在继承类中，最近的类将被调用。<br>如果没有一个error-page包含的exception-type与class-heirarchy相匹配。抛出的ServletException或其子<br>类异常，被引擎通过ServletException.getRootCause方法获得，获得后用这个异常再去配置的error<br>page列表中去匹配。<br>在部署描述文件中用exception-type元素定义的Error-page中exception-type的类名必须是唯一的。<br>当错误发生在servlet调用的RequestDispatcher中时error page机制是不能够干预到的；这样的情况如：<br>一个servlet用RequestDispatcher去调用另一个有错误的servlet。<br>如果一个servlet产生的错误没有被描述的错误页面机制所抓到，引擎必须设置response的状态码为500<br>9.10 Welcome Files<br>web应用可以在部署描述文件中定义一个welcome files调用的URI列表，这个机制的目的是允许开发者<br>定义自己的访问首页。<br>如果没有在部署描述中配置welcome 文件,引擎将把局部请求（没有指明具体访问资源，如<a href="http://www.cacolg/">www.cacolg</a>.<br>com/index.html,请求访问时用<a href="http://www.cacolg.com/">www.cacolg.com/</a>访问的）发送到适当的资源中，如：一个可能默认的<br>servlet，或列出该目录下的文件列表，或返回404响应错误。<br>一个例子：<br>1）在部署描述中定义index.html和default.jsp为welcome files<br>2）定义一个servlet的mapping路径为/foo/<br>WAR中有的文件如下：<br>/foo/index.html<br>/foo/default.html<br>/foo/orderform.html<br>/foo/home.gif<br>/catalog/default.jsp<br>/catalog/products/shop.jsp<br>/catalog/products/register.jsp<br>3）请求的URI为 处理后的URI<br>/foo 或 /foo/ /foo/index.html<br>/catalog/ /catalog/default.jsp<br>/catalog/index.html 404 not found<br>/catalog/products/ 404 not found 也可能返回shop.jsp and /or register.jsp 列表。<br>9.11 web应用环境<br>j2EE定义的命名环境能够使得应用在不需要知道外部信息怎么命名的情况下比较方便的访问资源或外部<br>信息。<br>servlet作为j2EE完整的一部分，使web应用部署描述文件提供了一个servlet可以访问资源和EJB，这些<br>部署描述元素有：<br>.env-entry<br>.ejb-ref<br>.ejb-local-ref<br>.resource-ref<br>.resource-env-ref<br>开发者使用这些元素描述web应用中需要用到的对象，这些对象都要在web容器运行时注册到JNDI命名<br>空间。<br>在J2EE1.3版本j2EE的环境需求中，servlet引擎不是J2EE技术的一部分，web环境要提供的功能在J2EE<br>规范中有描述。如果没有实现支持环境所要提供的功能，在发布应用时，web容器就会抛出警告。<br>实现servlet引擎在J2EE中是需要的，应该被纳入J2EE1.3中。J2EE1.3应该提供更多的内容。<br>servlet引擎必须支持对象的lookup方法，查找对象并在引擎控制的线程中实例化。<br>servlet引擎应该支持开发者创建的线程，因为应用创建的线程不是很轻便，开开发者不得不依赖于这些<br>功能有限的线程。这些需求将被加入到下一个版本的servlet规范中。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第十章 应用周期事件<br>10.1 介绍<br>事件是servlet2.3种新添的内容。应用事件使得web开发者能够控制ServletContext和HttpSession对象的<br>信息交互，使得管理web使用的资源更有效，方便。<br>10.2 事件监听器<br>事件监听器是实现了servlet事件监听接口的类。在web发布是这些监听类就被实例化和注册在web容器<br>中。<br>servlet事件监听器提供了在ServletContext和HttpSerssion对象状态发生改变时触发的事件。Servlet<br>cotext监听器用于管理应用的资源或虚拟机的状态。HTTP session监听器管理与会话关联的资源。<br>可以有多个监听器监听每一个事件类型。开发者可以指定引擎调用监听类的顺序。<br>10.2.1 事件类型和监听接口<br>Event Type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;ListenerInterface&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说明<br>Lifecycle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;javax.servlet.ServletContextListener&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当servlet context被创建并有效的<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;接受第一个请或servlet context销毁前<br>Changes to attributees javax.servlet.ServletContextAttributesListener&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当servlet context中的属性发生<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; added,removed,replaced<br><br>Lifecycle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; javax.servlet.http.HttpSessionListener&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当HttpSession被创建，无效或超时<br>Changes to attributes&nbsp; &nbsp;javax.servlet.HttpSessionAttributesListener&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当属性added,removed或replaced时<br>10.2.2 一个使用监听的例子<br>一个简单的web应用中有servlet要访问数据库，开发者提供一个context 监听类管理数据库连接。<br>1）web应用启动时，监听类被装载，登陆数据库，在servlet context中保存数据库连接。<br>2）servlet访问数据库连接<br>3）当web服务销毁时，或应用从web服务中删除时，关闭数据库连接。<br>10.3 监听类的配置<br>10.3.1 对监听类的规定<br>web开发者提供实现了以上监听接口的类，每个类应该有一个没有参数的构造器函数。监听类放在<br>WEB-INF/classes下或以一个jar文件放在WEB-INF/lib下都可以。<br>10.3.2 部署描述<br>web容器对每个监听类只会创建一个实例，在第一个请求到来之前实例化并注册。web容器注册监听类<br>的顺序根据他们实现的接口和在部署描述文件中定义的顺序。web应用调用监听实例的顺序按照他们注<br>册的顺序。<br>10.3.4 在销毁时的事件<br>当应用销毁时监听事件的执行顺序按部署描述中的顺序，先执行session中的监听事件再执行context中<br>的监听事件。session的无效事件必须在context的销毁事件之前被调用。<br>10.4 部署描述的例子<br>下面给出注册两个servlet cocntext lifecycle监听器和一个HttpSession监听器的例子。<br>Com.acme.MyconnectionManager和com.acme.MyLoggingMoudule都实现了javax.<br>servletServletContextListener接口,com.acme.MyloggingModule另外还实现了javax.servlet.<br>HttpSessionListener接口。开发者希望com.acme.MyConnectionManager在com.acme.<br>MyLoggingModule之前管理者servlet context 的生命周期事件。部署描述文件如下：<br>&lt;web-app&gt;<br>&lt;display-name&gt;MyListeningApplication&lt;/display-name&gt;<br>&lt;listener&gt;<br>&lt;listener-class&gt;com.acme.MyConnectionManager&lt;/listener-class&gt;<br>&lt;/listenrer&gt;<br>&lt;listenrer&gt;<br>&lt;listenrer-class&gt;com.acme.MyLoggingModele&lt;/listener-class&gt;<br>&lt;/listener&gt;<br>&lt;sevlet&gt;<br>&lt;display-name&gt;RegistrationServlet&lt;/display-name&gt;<br>..etc<br>&lt;/servlet&gt;<br>&lt;/web-app&gt;<br>10.5 监听器的实例和线程<br>在第一个请求被web容器接受之前实例化并注册好监听器类是必须的。监听器在整个web应用生命周期<br>中都要使用。<br>ServletContext和HttpSession对象属性的改变可能会同时产生，引擎不需要同步这些属性类的事件。<br>10.6 分布式容器组<br>在分布式web容器组中，HttpSession和ServletContext实例只活动与它们本地的JVM中。在分布式web容<br>器中，监听实例会在每一个web容器中创建实例。<br>10.7 session事件<br>监听器使得开发者可以跟踪web应用中的session。知道session是否变得无效是经常被用到的，因为<br>session超时时引擎会使session变得无效，或应用会调用invalidate方法。<br></p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/zhuyan/aggbug/138196.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyan/" target="_blank">朱岩</a> 2007-08-20 17:43 <a href="http://www.blogjava.net/zhuyan/articles/138196.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Servlet2.3中文文档(第6,7章)</title><link>http://www.blogjava.net/zhuyan/articles/138195.html</link><dc:creator>朱岩</dc:creator><author>朱岩</author><pubDate>Mon, 20 Aug 2007 09:35:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyan/articles/138195.html</guid><wfw:comment>http://www.blogjava.net/zhuyan/comments/138195.html</wfw:comment><comments>http://www.blogjava.net/zhuyan/articles/138195.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyan/comments/commentRss/138195.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyan/services/trackbacks/138195.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第六章<br>6 Filtering<br>Fileter是servlet2.3新增的部分。这一章介绍Filter类和方法，以及在web工程中的配置。<br>6.1什么是Fileter<br>Filter是重复使用的，用于变换HTTP请求和响应以及头信息中的内容。Filter不能像servlet那样创建<br>response响应，但可以修改请求和响应的内容。<br>6.1.1例举一些Filter<br>验证Filter<br>登陆，审核Filter<br>图像处理Filter<br>数据压缩Filter<br>加密Filter<br>XSL/T Filter<br>MIME Filter<br>6.2 主要观念<br>开发者通过创建实现javax.servlet.Filter接口的类，并提供一个没有参数的构造函数来创建一个Filter。<br>在描述文件中Fileter用filter表示，调用方法用filter-mapping进行配置。<br>6.3 Filter生命周期<br>在web工程发布后，在请求使引擎访问一个web资源之前，引擎必须定位Filter列表；引擎必须确保为列<br>表中的每一个Filter建立了一个实例，并调用了他们的init(FilterConfig config)方法。在这过程中可以抛<br>出异常。<br>部署描述文件中定义的所有filter，仅会在引擎中产生一个实例。<br>引擎为filter提供了一个FilterConfig类，该类附有ServletContext和一个带有初始化参数的set。<br>当引擎接受一个请求时，引擎就会调用filter列表中第一个filter的doFilter方法，把ServletRequest，<br>ServletResponse和FilterChain作为参数传给它。<br>filter中doFilter方法典型的处理步骤是：<br>1）检查请求头信息<br>2）开发者创建一个实现了ServletRequest或HttpServletRequest的类，去包装request对象，以<br>便修改请求的头信息或体数据。<br>3）开发者创建一个实现了ServletReqponse或HttpServletResponse的类，去包装response对<br>象，以便修改请求的头信息或体数据。<br>4)filter可以调用链中的下一个实体，下一个实体是另一个filter，如果该filter是列表中最后的一<br>个，则它的下一个实体就是一个目标web资源。如果要调用下一个filter的doFilter方法，把<br>request，和response对象传给FilterChain对象的doFilter方法中就可以了。<br>Filter chain 的doFilter方法是由引擎提供的，引擎在该方法中会定位filter列表中的下一个filter，<br>调用它的doFilter方法，把传来的request和response对象传给它。<br>5）在调用chain.doFilter之后，filter可以检测响应的头信息<br>6）在这些过程中，filter可以抛出异常。当在调用doFilter过程中抛出UnavailableException异常<br>时，引擎重复尝试处理下面的filter chain的方法，如过时后还没请求到filter chain 就会关闭对<br>filter chain的请求。<br>当filter是列表中最后一个filter时，它的下一个实体是描述配置文件中filter后面的servlet或其它<br>资源。<br>在引擎删除一个Filter之前，引擎必须调用Filter的destroy方法，来释放资源。<br>6.3.1 包装Requests 和Responsees<br>过滤的中心观念是对request或response的包装，在这种模式下，开发者不仅可以改写存在的方法，还<br>可以创建自己的新方法，用于特殊的过滤任务，例如：开发者希望扩展response对象，希望有个更高层<br>次的输出流对象（writer）。<br>为了支持包装模式，引擎不许保证在整个过滤链中，传递的request和response对象都是同一个对象。<br>6.3.2 Filter的环境<br>Filter的初始参数可以在描述配置文件中用init-params元素来配置，在运行时中，用FilterConfig的<br>getInitParameter和getInitParamesterNames方法得到配置参数。<br>6.3.3 Filter在web工程中的配置<br>在部署描述文件中：<br>filter-name:filter名称<br>filter-class:filter类路径<br>init-params:用于初始化参数<br>如果开发者在部署描述中为一个filter类描述了两个定义，则引擎会创建这个filter类的两个实例。<br>下面是个配置的例子:<br>&lt;filter&gt;<br>&lt;filter-name&gt;Image Filter&lt;/filter-name&gt;<br>&lt;filter-class&gt;com.acme.ImageServlet&lt;/fiflter-class&gt;<br>&lt;/filter&gt;<br>一旦filter在部署描述中定义，filter-mapping就可以被定义了，filter-mapping在web应用中是定义关联<br>filter的servlet和静态资源的。<br>如：<br>&lt;filter-mapping&gt;<br>&lt;filter-name&gt;Image Filter&lt;/filter-name&gt;<br>&lt;servlet-name&gt;ImageServlet&lt;/servlet-name&gt;<br>&lt;/filter-mapping&gt;<br>Image Filter 的 Filter就和ImageServlet 的Servlet建立了关联。<br>Filter 可以和一群servlet和静态资源关联，用url-pattern。如：<br>&lt;filter-mapping&gt;<br>&lt;filter-name&gt;Loging Filter&lt;/filter-name&gt;<br>&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br>&lt;filter-mapping&gt;<br>引擎建立特殊请求URI的Filter链的顺序是:<br>1)url-pattern映射fiter-mapping的顺序和描述文件中定义的顺序是一样的。<br>2）servlet-name映射filter-mapping的顺序和描述文件中定义的顺序是一样的。<br>这种需求要求引擎在接受请求时：<br>.识别符合SRV.11.2规则的web资源。<br>.如果一些filter是servlet和有servlet-name的web资源匹配的，引擎就会创建一个和描述文件中<br>映射servlet-name的顺序一样的filter链。<br>.如果一些filter是rul-pattern关联的，引擎就会创建一个和描述文件中映射url-pattern的顺序一<br>样的efilter链。<br>一个高性能的web容器将会缓存filter链。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第七章 Sessions<br>超文本传输协议（HTTP）是无状态的协议。要建立一个有效的web应用，客户端之间的通信是需要<br>的。有很多会话跟踪的策略，<br>但是直接使用这些技术都很难使用。servlet规范中提供了一个简单的HttpSession接口，不需要开发者<br>关心会话跟踪的具体细节。<br>7.1 会话跟踪机制<br>下面描述了几种会话的跟踪机制<br>7.1.1 Cookies<br>HTTP cookies是最常用的会话跟踪机制，所有的servlet引擎都应该支持这种方法。<br>引擎发送一个cookie到客户端，客户端就会在以后的请求中把这个cookie返回给服务器。用户会话跟踪<br>的cookie的名字必须是JSESSIONID<br>7.1.2 SSL Sessions<br>在安全套接字层，加密技术用在了HTTPS协议，从一个客户端来的多个请求允许用一个含糊的标识，<br>servlet引擎就用这个数据定义一个Session。<br>7.1.3 URL重写<br>URL重写是最低性能的通用会话跟踪方法。当一个客户端不能接受cookie时，URL重写就会作为基本的<br>会话跟踪方法；URL重写包括一个附加的数据，一个session id，这样的URL会被引擎解析和一个session<br>相关联。一个session id是作为URL的一个被编码的参数传输的，这个参数名字必须是jsessionid.如下面<br>的例子：<br><a href="http://www.myserver.com/catalog/index.html;jsessionid=1234">http://www.myserver.com/catalog/index.html;jsessionid=1234</a><br>7.1.4 会话的完整性<br>一个web容器必须支持HTTP 会话。而当cookies方法不被支持时，通常使用URL重写方法。<br>7.2 创建一个会话<br>servlet设计者必须考虑到一个客户端不能加入session的情况。<br>7.3 会话范围<br>HttpSession对象只在应用程序级有效，通常用于session的cookie可以服务于不同的上下文，但一个<br>HttpSession实例只服务于一个会话。举个例子：如一个servlet A用RequestDispatcher去调用另一个web<br>应用中的另一个servlet B，用于A和B的会话一定是两个不同的会话。<br>7.4 Session属性的邦定<br>一个servlet可以通过一个name邦定一个对象到HttpSession实例中；只要获得包含同一个会话的请求对<br>象，任何邦定到会话中的对象在同一个ServletContext中对于其它的servlet都是可用的。<br>当把一个对象放入session或从session删除时可能要通知其它对象，这些信息能够被实现了<br>HttpSessionBindingListener接口的对象获得，这个接口定义了一下的一些方法。<br>valueBound<br>valueUnbound<br>valueBound方法在HttpSession接口调用getAttribute方法获得一个有效的对象之前调用。valueUnbound<br>方法在HttpSession接口调用getAttribute方法获得一个不再有效的对象后调用。<br>7.5 会话超时</p>
<p>在HTTP协议中，当客户端不再有效时，没有清楚的定义终止信号。这就意味着通常只能采用时间超时<br>来表明客户端不再有效。<br>默认的超时时间是servlet引擎定义的，通过HttpSession的getMaxInactiveInterval方法可以得到超时的<br>时间；开发者可用用setMaxInactiveInterval方法来设置超时的时间，以秒定义的。如果一个session的<br>超时时间被设置为-1，则这个session将永远有效。<br>7.6 最后访问时间<br>在当前的请求中用HttpSession接口的getLastAccessedTime可以获得最后一次访问session的时间。<br>7.7 重要session<br>7.7.1 线程问题<br>在一个可以配置的应用中，所有的请求都是一个会话的一部分，引擎一定能够取出通过setAttribute或<br>putValue放入HttpSession对象中的对象。注意以下的情况：<br>.引擎一定能够访问实现了Serializable接口的对象。<br>.引擎可以选择存储HttpSession对象中指定的对象，如EJB组件和事务。<br>.引擎能够监听到会话的变动。<br>如果放入session中的对象没有被Seializable或没有效，servlet可以抛出IllegalArgumentException；如果<br>引擎不支持Session存储对象的机制，引擎一定会抛出IllegalArgumentException。<br>这些限制意味着，在一个分布式引擎中，不会有额外的并发问题。<br>如果引擎为了service的品质持续化或迁移session，使用本地持续化的HttpSession或它的属性是不受限<br>制的，开发者要想确保放入session中的属性对象能够可用，最好对象实现Serializable接口。<br>在迁移一个session时引擎必须通知session中实现了HttpSessinActivationListener的属性对象，必须通知<br>在序列化前钝化的或序列化后激活的session的监听器。<br>开发分布式的开发者应该清楚的是，一旦引擎运行在超过一个JVM的时候，就不能用static 表明变量来<br>存储应用状态，应该用EJB或数据库赖存储。<br>7.7.3客户端<br>因为cookies或SSL证书都是被web浏览器访问过程控制的，与任何特殊的window浏览器是没有关系的。<br>所以从所有window客户端到一个servlet引擎的请求是同一个会话的一部分。最好是开发者总是设想所<br>有的window客户端是一起参与同一个会话的。</p>
<img src ="http://www.blogjava.net/zhuyan/aggbug/138195.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyan/" target="_blank">朱岩</a> 2007-08-20 17:35 <a href="http://www.blogjava.net/zhuyan/articles/138195.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Servlet2.3中文文档(第4,5章)</title><link>http://www.blogjava.net/zhuyan/articles/138193.html</link><dc:creator>朱岩</dc:creator><author>朱岩</author><pubDate>Mon, 20 Aug 2007 09:31:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyan/articles/138193.html</guid><wfw:comment>http://www.blogjava.net/zhuyan/comments/138193.html</wfw:comment><comments>http://www.blogjava.net/zhuyan/articles/138193.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyan/comments/commentRss/138193.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyan/services/trackbacks/138193.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第四章<br>4 requeset<br>request对象包含了客户端的所有请求信息。在HTTP协议中，客户端发送到服务端的信息都包<br>含在请求的HTTP 头和消息体中<br>4.1 HTTP 协议的参数<br>客户端发送给servlet引擎的参数是包含在请求中的，引擎从客户端请求的URI字符串中或POST数据中解<br>析出请求的参数。参数以name-value的形式存储的。任何一个name可以对应多个value。在<br>ServletRequest接口的方法中：<br>getParameter<br>getParameterNames<br>getParameterValues<br>getParameterValues方法返回关联到一个name上的一个String对象的数组。getParameter返回name对<br>应的values数组中的第一个value。URI和POST体中的参数都会放入请求参数的set对象中。URI中的参<br>数会在POST体之前被引入，如URI中的参数&#8220;a=hello&#8221;post体中的参数是a=goodbye&amp;a=world,则参数set<br>中的内容是a=(hello,goodbye,world).以HTTP GET请求的参数是不隐蔽的，参数必须通过<br>getRequestURI或getPathInfo方法获得参数字串。<br>4.1.1 参数什么时候有效<br>在post form中的数据参数被放入参数set之前的情况是这样的：<br>1）请求是一个HTTP或一个HTTPS<br>2）HTTP方法是POST<br>3）内容的类型是application/x-www-form-urlencoded<br>4）初始化过的servlet从request对象中调用getParameter方法（或getParameterNames，<br>getParameterValues）。<br>Post form 中的数据符合条件的就放入参数set中，不符合的就放入request对象的输入流中。<br>4.2 属性<br>request的属性是一个对象，引擎可以把API不能表达的信息放入属性中，一个servlet也可以设<br>置一个属性信息用于servlet之间的通信。request对象中的属性方法有：<br>getAttribute<br>getAttributeNames<br>setAttribute<br>一个属性名称只能关联一个value。属性名以&#8220;java.&#8221;或&#8220;javax.&#8221;为前缀的是规范保留的，类似<br>的&#8220;sun.&#8221;&#8220;com.sun&#8221;是sun公司的保留字，这些保留的前缀是不能使用的。name建议使用统一的<br>包命名规范名称。<br>4.3 头<br>servlet通过HttpServletRequest接口的方法获得HTTP的包头信息，这些方法是：<br>getHeader<br>getHeaders<br>getHeaderNames<br>getHeader 方法返回头的名称。一个名称可以关联多个头信息，如果在这种情况下，getHeader<br>方法返回第一个头信息。<br>getHeaders返回与一个名称关联的所有头信息存放在Enumeration对象中。HttpServletRequest<br>提供了一些提取头信息的类型转换方法，如：<br>getIntHeader 把头信息中的数据转换成int型，如果转换失败会报NumberFormatException错<br>误。<br>getDateHeader 把头信息中日期的数据转换成date型，如果转换失败会报<br>IllealArgumentException错误<br>4.4 请求路径<br>context路径：这路径是和ServletContext对象关联的，在web服务中默认的上下文路径是空的字</p>
<p>符串，如果上下文路径不是web服务的根目录，则路径以&#8216;/&#8217;字符开始，但不能以&#8216;/&#8217;结束。<br>Servlet 路径：与该请求匹配的servlet的路径。该路径以&#8216;/&#8217;字符开头，或以&#8216;/*&#8217;开头但后面为空字<br>串。<br>路径信息：是请求路径的一部分，但不是context路径的一部分，也不是Servlet路径的一部分，<br>它既不为null也不是以&#8216;/&#8217;开头的字符串。<br>上一路径在HttpServletRequest接口中对应的方法是：<br>getContextPath<br>getServletPath<br>getPathInfo<br>requestURI = contextPath + servletPath + pathInfo<br>上下文配置的例子：<br>Conteext Path /catalog<br>Servlet Mapping Pattern:/lawn/*<br>Servlet:LawnServlet<br>Servlet Mapping Pattern:/garden/*<br>Servlet:GardenServlet<br>Servlet Mapping Pattern:*.jsp<br>Servlet:JSPServlet<br>观察下面的路径<br>Request path path Elements<br>/catalog/lawn/index.htm ContextPath:/catalog<br>ServletPath:/lawn<br>PathInfo:/index.html<br>/catalog/garden/implements/<br>ContextPath:/catalog<br>ServletPath:/garden<br>PathInfo:/implements/<br>/catalog/help/feedback.jsp<br>ContextPath:/catalog<br>ServletPath:/help/feedback.jsp<br>PathInfo:null<br>4.5 路径转换<br>在API中有两个简单的方法允许开发者获得文件系统的路径：<br>ServletContext.getRealPath<br>HttpServletRequet.getPathTranslated<br>getRealPath(String aPath)方法返回本地文件系统的绝对路径。getPathTranslated方法计算出请<br>求pathInfo中的绝对路径。<br>以上的两个方法，servlet引擎不能辨认文件的路径是否有效，当web应用调用一个不确定远程<br>文件系统，或数据库路径中的文件时，会返回null<br>4.6 Cookies<br>HttpServletRequest接口中提供了getCookies方法返回请求中的cookies数组，在每次客户端请求<br>时cookies数据就从客户端发送给服务。客户端返还的部分cookie信息是cookie的name和cookie<br>的value。当cookie被送入浏览器时，cookie的其它信息就可以设置了。<br>4.7 SSL 属性<br>如果一个请求被转给一个安全的协议，如HTTPS，这些信息必须暴露给ServletRequest接口的<br>isSecure方法。web引擎必须把下面的信息暴露给servlet开发者：<br>Attribute Attribute Name javaType<br>Cipher suite javax.servlet.request.cipher_suite String<br>bit size of the algo-rithm javax.servlet.request.key_size Integer<br>如果一个SSL证书伴随着一个请求，servlet引擎必须把它作为一个数组对象暴露给servlet开发<br>者，该数组中有<br>java.security.cert.X509Certificate对象和放在ServletRequest属性中的javax.servlet.request.<br>X509Certificate对象。<br>数组排列的顺序是升序，在链中的证书的顺序就是客户端设置的顺序。<br>4.8 国际化<br>ServletRequest接口的方法中提供了的方法：<br>getLocale<br>getLocales<br>getLocale方法将返回客户端将从中获得内容的首选的locale。要想知道更多的关于Accept-<br>Language header 怎么解释客户端首选的语言的，请看14.4章<br>getLocales方法返回一个Locale objects的Enumeration,从首选的locale开始递减。<br>如果客户端没有制定首选的locale，servlet引擎一定要提供一个默认的locale供getLocale方法返<br>回，getLocales方法必须包含一个默认的locale的locale element<br>4.9 Request 数据的编码<br>有许多web浏览器不能发送一个编码的头内容，所以把编码留给解读HTTP请求的Read去做。对<br>于默认的请求编码，引擎通常创建一个reader用&#8220;ISO-8859-1&#8221;去解析POST的数据，如果客户端<br>没有指明编码，或者客户端发送失败，getCharacterEncoding方法就返回null。<br>如果客户端没有设置编码，而请求需被另外一种编码，可用ServletRequest接口中的<br>setCharacterEncoding(String enc) 方法。必须在解析post数据或读取请求流之前调用这些方<br>法。<br>4.10 Request对象的生命周期<br>每个request对象仅在servlet的service方法或filter中的doFilter方法中有效，引擎重用request对<br>象是为了降低创建request对象的性能消耗。<br>开发者必须清楚request对象在给定的范围外的一些不确定的行为。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第五章<br>response对象封装着服务端送给客户端的信息，从服务端传回的信息可以包含在请求的头和消息体重。<br>5.1 缓存<br>servlet引擎支持应答缓存，典型的servlet会默认的执行缓存，servlet可以指定缓存参数。<br>设置缓存信息的方法在ServletResponse接口中的方法有：<br>getBufferSize<br>setBufferSize<br>isCommitted<br>Reset<br>resetBuffer<br>flushBuffer<br>这些方法只有在servlet调用ServletOutputStream 或Writer之前有效。<br>getBufferSize返回缓存的大小，如果没有缓存，该方法返回0。<br>setBufferSize可以设置缓存的大小，但不是必须的。servlet会根据请求放置适当的缓存大小。这方<br>法必须在servlet调用ServletOutputStream 或Writer方法之前被调用。如果在之后调用就会抛出<br>IllegalStateException错误。<br>isCommitted返回一个boolen值，标志是否有任何一个字节的数据被返回给客户端了。flushBuffer<br>方法强制把缓存中的信息写到客户端。<br>当response没有提交缓存内容时调用reset方法就会清除缓存中的信息，包括头信息和状态码。<br>resetBuffer方法会清除缓存中的信息，但不会清除头和状态码。在commit之后调用reset或<br>resetBuffer都会抛出IllegalStateException错误，缓存中的内容不受影响。<br>使用缓存时，当缓存满时response就必须立刻刷新把缓存中的内容发送给客户端；只要第一个字节<br>到了客户端，commit的状态就为true。<br>5.2 Headers<br>servlet能够通过HttpServletResponse的一些方法设置HTTP响应的头信息，这些方法有：<br>setHeader<br>addHeader<br>setHeader方法会把给定的一个name-values放到头信息中，头信息中只能有一个name-values，后面<br>setHeader会覆盖前面setHeader方法中的内容，一个name可以有多个value。<br>addHeader方法可以增加一个value到已有的name上，如果name不同就会新建一个name-values<br>头可以包含一些信息，如日期或数字对象。<br>以下的一些方法用适当的数据类型设置头信息：<br>setIntHeader<br>setDateHeader<br>addIntHeader<br>addDateHeader<br>在响应被发送到客户端之前，头信息是必须被设置的，如果没有设置头信息，servlet引擎将不会发送该<br>请求到客户端。HTTP1.1规范没有规定必须设置响应的头信息。当程序员没有设置响应体的Content-<br>Type时，servlet引擎也不需要设置一个默认的类型。<br>5.3 其他一些方法<br>HttpServletResonse接口中还有其他的一些方法：<br>sendRedirect<br>sendError<br>sendRedirect方法将设置合适的头和体信息，用于重定向客户端到另一个URL。如果sendRedirect参数<br>是个相对路径，则在底层servlet引擎中会把这相对路径转换成绝对路径返回给客户端的。<br>如果相对路径不能被引擎转换成绝对路径就会抛出IllegalArgumentException错误。<br>sendError方法会把一条错误信息作为头和体信息发送给客户端。<br>如果在调用sendRedirect或sendError之前设置了头和体信息，再调用sendRedirect或sendError时，之前<br>的头和体中的数据信息都将没用，不会被发送到客户端。如果使用了缓存，在调用sendRedirect或<br>sendError时，之前的信息都将被清除。如果在commit之后调用sendRedirect或sendError就会抛出<br>IllegalStateException错误。<br>5.4 国际化<br>当客户端用一特殊的语言（或客户端设置了语言）发出请求时，servlet会设置相应的响应语言信息，<br>ServletResponse接口中设置响应语言的方法是setLocale。这个方法会设置一个合适的Content-<br>Language到头信息中。最好是开发者在调用getWriter方法之前调用setLocale方法，确保返回的<br>PrintWriter已经被设置好了语言信息。如果在调用setLocale之后又调用了setContentType，setLocale中<br>的内容将被setContentType中的字符集覆盖。<br>response默认的编码方式是&#8220;ISO-8859-1&#8221;。<br>5.5 response对象的关闭<br>当response被关闭时，引擎必须刷新该response缓存中的所有内容到客户端。关闭的顺序是：<br>1）关闭servlet的service方法<br>2）response 中setContentLength方法设置的指定数量的信息被写入response<br>3）调用sendError方法<br>4）调用sendRedirect方法<br>5.6 response对象的生命周期<br>每个response对象仅在servlet的serrvice方法或filter的doFilter的方法中有效。引擎重复使用reponse对<br>象，是为了降低创建response对象的开销。开发者必须注意response对象在指定范围外可能出现的一些<br>意外的行为。</p>
<img src ="http://www.blogjava.net/zhuyan/aggbug/138193.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyan/" target="_blank">朱岩</a> 2007-08-20 17:31 <a href="http://www.blogjava.net/zhuyan/articles/138193.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Servlet2.3中文文档(第1,2,3章)</title><link>http://www.blogjava.net/zhuyan/articles/138192.html</link><dc:creator>朱岩</dc:creator><author>朱岩</author><pubDate>Mon, 20 Aug 2007 09:28:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyan/articles/138192.html</guid><wfw:comment>http://www.blogjava.net/zhuyan/comments/138192.html</wfw:comment><comments>http://www.blogjava.net/zhuyan/articles/138192.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyan/comments/commentRss/138192.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyan/services/trackbacks/138192.html</trackback:ping><description><![CDATA[<p align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>第一章</strong><br>servlet2.3规范用到了一下的一些规范：J2EE、JSP1.1、JNDI<br>在14章中讲述了规范中的所有的classes类或接口（改文中不讲述）。对开发者而言以下的有些相关的<br>协议：URI、URL、HTTP/1.0、MIME、HTCPCP/1.0、XML<br>1.1 什么是servlet？<br>servlet是一个基于java技术的web组件，该组件被容器管理，能被编译成字节码被web服务调<br>用；容器也被称之为引擎，是支持servlet功能的web服务的扩展。servlet之间的通信是通过客户<br>端请求被引擎执行成request/response对象进行的。<br>1.2 什么是servlet引擎？<br>servlet引擎是web服务器或应用服务器的一部分，服务器能够支持网络的请求/响应，基于请求<br>解析MIME，基于响应格式化MIME。servlet引擎是一个servlet容器，也掌管着servlet的生命周<br>期。<br>所有的servlet引擎都必须支持HTTP的请求/响应模式，但HTTPS的请求/响应模式也是被支持<br>的。HTTP的版本最小要HTTP/1.0，最好是HTTP/1.1。servlet引擎也具有安全和权限的一些特<br>性，这些特性其服务器应提供。<br>1.3 例子<br>一个典型的事件执行的顺序是：<br>1) 客户端向web服务器发起一个HTTP请求<br>2) HTTP请求被web服务器接受，并移交给servlet引擎，servlet引擎可以在主机的<br>同一个进程、不同的进程或其他的web服务主机的进程中启动。<br>3) servlet引擎根据servlet的配置档确定调用的servlet，并把request对象、<br>response对象传给它。<br>4) 4．servlet通过request对象知道客户端的使用者是谁，客户的请求信息是什么<br>和其他的一些信息。servlet处理完请求后把要返回的信息放入response对象返回到<br>客户端<br>5） 一旦servlet完成了请求的处理，servlet引擎就会刷新response，把控制权返回给<br>web服务器</p>
<p>1.4与其它技术的比较<br>与其它服务相比servlet有以下的一些优点<br>1) 运行速度上比CGI快，因为使用了多线程<br>2) servlet使用了标准的api，可被许多web服务支持<br>3) 与系统无关性，一次编译多次使用<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>&nbsp;&nbsp; 第二章<br></strong>servlet接口是servlet api核心部分，所有的servlet都是直接或间接的实现了这些接口。两个最重<br>要的servlet api 接口是GenericServlete 和 HttpServlet，更多的开发者都继承HttpServlet去实现<br>他们的servlet<br>2.1 Request 包含的方法<br>一个基本的servlet接口应该定义一个方法包含客户端的信息，每次servlet引擎把一个request发<br>送到一个servlet事例，这个方法都要被调用。<br>对于并发的请求，web应用需要设计者设计的servlet引擎能分配多个线程执行这个方法。<br>2.1.1 HTTP 请求处理的方法<br>HttpServlet是实现了Servlet接口的抽象类，增加了一些新的方法，这些方法在处理HTTP请求时<br>会被service方法自动调用，这些方法是：<br>doGet 接受 HTTP 的GET请求<br>doPost 接受 HTTP 的POST请求<br>doPut 接受 HTTP的PUT请求<br>doDelete 接受 HTTP的DELETE请求<br>doHead 接受 接受 HTTP的HEAD请求<br>doOptions 接受 HTTP的OPTIONS请求<br>doTrace 接受 HTTP的TRACE请求<br>一个开发者只会涉及到doGet和doPost方法，其它的方法是为非常熟悉HTTP的设计师准备的</p>
2.1.2<br>HTTP/1.0只定义了doGet，doHead，doPost方法，没有定义PUT，DELETE，OPTIOONS和<br>TRACE方法<br>2.1.3<br>HttpServlet接口定义了getLastModified方法<br>2.2 实例数<br>2.2.1<br>在分布式环境中servlet引擎为每个servlet只能声明一个实例，当一个servlet实现了<br>SingleThreadModel接口时，servlet引擎可以声明多个实例去处理请求，servlet在应用服务的部<br>署描述中定义发布.<br>2.2.2单线程servlet<br>SingleThreadModel接口保证了在同一时刻一个servlet实例的service方法只会被一个线程执行。<br>这对于每个请求发送给每个实例是很重要的。引擎可以从对象池中选择，对象池可以在同一时<br>刻保持多个实例，如HttpSession可以被多个servlet在任何时候调用包括实现了<br>SingleThreadModel接口的servlet<br>2.3 servlet的生命周期<br>一个好的生命周期的定义应该是servlet怎么被引入了，怎么实例化的，怎么初始化的？当请求从客<br>户端来的时候，是怎么从服务器中取出来的，这些在javax.servlet.Servlet的接口的init，service，<br>destroy方法中都有明确的定义。<br>所有的servlet都必须实现GenericServlet或HttpServlet抽象类<br>2.3.1 servlet的引入和实例化<br>servlet引擎会可靠的引入和实例化servlet，当servlet引擎被启动时servlet就被引入和实例化了，<br>或者当一个servlet被请求时被引擎引入和实例化。<br>servlet引擎启动时，需要装载的类通过java的装载类进行装载，被装载的类可以在本地文件系<br>统、远程文件系统或网络服务中。在装载完后，引擎就实例化它们。<br>2.3.2 初始化<br>在servlet对象实例化后，引擎必须在这个servlet接受客户段请求之前初始化，在初始化中<br>servlet可以读取固定的配置信息，一些昂贵的资源如数据库连接和一次性激活的资源，引擎通<br>过调用servlet接口的init方法初始化。每个serlet对象都实现了Servlet接口和ServletConfig接口,<br>ServletConfig接口允许servlet接受web应用配置档中配置的参数，还向servlet中传入了一个描述<br>servlelt运行环境的类（ServletContext）<br>2.3.2.1 在初始化时发生错误<br>在初始化过程中，servlet实例能抛出UnavailableException 或ServletException异常。在这样的<br>情况下servlet不能被放入服务中，必须被引擎释放，destroy方法没有被调用。在初始化失败后<br>引擎可以在UnavailableException异常规定的最短无效时间后实例化新的一个实例，再初始化。<br>2.3.3 request<br>当servlet初始化完成后，引擎可以使用它去处理客户端的请求了。请求被封装在Servletrequest<br>类型的对象中，响应信息被封装在ServletResponse类型的对象中，这两个对象以参数的形式传<br>给Servlet接口中的service方法。<br>2.3.3.1 多线程问题<br>servlet引擎可以发送并发的请求给servlet的service方法，servlet开发者必须提供足够的线程来<br>运行service方法。<br>对开发者来说一个可以选择的方法是实现SingleThreadModel接口，以确保在同一时刻只有一个<br>请求在service方法中。一个引擎要确保请求能够在servlet中持续化，或维持在一个servlet实例<br>池中，如果servlet是web应用服务的一部分，引擎可以在一个虚拟机中拥有一个servlet实例化的<br>池。<br>对于没有实现SingleThreadModel接口的servlet，如果service方法（或 doGet，doPost）被声明<br>为synchronized，引擎将不能用实例池的途径，而必须持续化请求，强力建议开发者不能声明<br>synchronize service方法，这样会严重影响系统的性能。<br>2.3.3.2 request中的异常<br>在处理请求时servlet可以抛出ServletException或UnavailableException异常，一个<br>ServletException异常会在处理一个请求出现错误时抛出，引擎将清除这个异常。当servlet一时<br>或永久地不能获得一个请求时就会抛出UnavailableException异常,如果是一个永久性异常时引擎<br>将调用它的destroy方法从服务器中消除servlet实例，如果是暂时性异常时引擎在异常期间不发<br>送请求给servlet。如果返回SERVICE_UNAVAILABLE(503)响应，在这期间引擎将不接受任何请<br>求，直到header中出现Retry-After。引擎可以不区分永久性还是暂时性的异常把所有的<br>UnavailableException作为永久性处理。<br>2.3.3.3 线程安全<br>执行request和response对象不能保证是线程安全的，意思是说他们只能在请求的线程中使用，<br>不能被其它线程中的对象使用。<br>2.3.4 结尾<br>servlet实例可能被引擎保存几毫秒或和引擎一样的生命时间或在这两者之间。当引擎决定结束<br>一个servlet时，调用它的destroy方法，在destroy中释放任何长久固定的资源。<br>在引擎调用desroy方法之前，必须保证运行在service方法中的线程都完成处理，或者超过了服<br>务定义的执行时间。<br>一旦servlet实例的destroy方法被调用，引擎不在发送任何请求给这个实例。如果引擎再次使用<br>这个servlet就必须再建一个这个servlet的实例。<br>在destroy方法执行完成后，引擎将释放这个servlet实例，于是就符合垃圾回收机制的条件了。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>第三章</strong><br>3.1 介绍ServletContext接口<br>ServletContext接口定义了servlet运行环境的信息。引擎提供商有义务在servlet引擎中提供一个<br>实现了ServletContext接口的对象。通过这个对象servlet能够获得log事件，资源的URL，设置或<br>存储servlet之间通信的变量。ServletContext在web服务中确定了一个所有请求开始的路径，是<br>ServletContext的上下文路径。<br>3.2 ServletContext 接口的作用范围<br>每个web应用配置到容器中都会产生一个实现了ServvletContext接口的实例。如果是分布式<br>的，将会在每个java虚拟机上产生一个ServletContext实例。容器中默认固有的web应用（不是<br>发布上来的web应用）有一个默认的ServletContext，在分布式中这个默认的ServletContext只存<br>在于一个虚拟机中，是不可分配的。<br>3.3 初始化参数<br>ServletContext接口的getInitParameter,getInitParameterNames方法接受部署描述文件中的初始<br>化参数，这些参数可以是的安装信息，或网站管理员的mail或名字或对系统的评论。<br>3.4 上下文属性<br>servlet可以通过一个名称把对象邦定到servletContext中，帮定到ServletContext中的对象都能被<br>同一个web服务中的其它对象引用。ServletContext中的属性方法有：<br>setAttribute<br>getAttribute<br>getAttributeNames<br>removeAttribute<br>3.4.1 在分布式系统中 上下文的属性<br>上下文属性是在本地的虚拟机中保存的，这防止了ServletContext属性存在于分布式的内存中。<br>当信息需要在一个分布式环境中共享的时候，信息应该被放在session中，或存在数据库中，或<br>存在一个实体bean中。<br>3.5 资源<br>ServletContext接口提供了获取web服务中的静态资源的方法：<br>getResource<br>getResourceAsStream<br>这些方法以一个&#8220;/&#8221;作为上下文的根目录，后跟着资源路径的路径为参数。这些资源可以在本地<br>服务系统中也可以在另个web应用中，或在一个远程的文件系统中。<br>这些方法不能用于去获得一个动态的资源，如要调用一个jsp页面，getResource("/index.jsp")将<br>返回index.jsp的原代码，不能web显示index.jsp。<br>要获得资源列表可以用getResourcePaths(String path)方法<br>3.6 多主机 和 Servlet 上下文<br>web服务中可能在一个IP上有多个逻辑主机的情况。在这种情况下每个逻辑主机必须有自己单<br>独的servlet上下文，或者设置多个servlet 上下文，但在逻辑主机中不能共享这些servlet 上下<br>文，一个主机只能单独使用一个。<br>3.7<br>引擎提供类重新装载机制是必须的，必须确认应用中所有的类和接口都可以在单类装载器中<br>装载；在session绑定监听事件中引擎会终止正在装在的类。以前版本的装载器，引擎创建一<br>个新的装载器装载一个servlet或class和类装载器装载其他的servlet或类截然不同；这可能装<br>载一个未知的类或对象，产生不可预知的行为。这是新的类装载器中是应该注意预防的问<br>题。<br>3.7.1 临时工作目录<br>Servlet 上下文需要一个临时存储的目录。servlet引擎必须为每个servlet 上下文提供一个私有临<br>时目录，通过javax.servlet.context.tempdir的context属性使目录有效。与该属性关联的对象必<br>须是java.io.File类型。<br>在许多servlet引擎实现中提供请求可以识别的通用的机制。<br>当servlet引擎重起始不必维护临时目录中的内容，但要确保临时目录中的该上下文内容对于运<br>行在该servlet引擎中的其它web应用中的servlet 上下文是不可见的。
<img src ="http://www.blogjava.net/zhuyan/aggbug/138192.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyan/" target="_blank">朱岩</a> 2007-08-20 17:28 <a href="http://www.blogjava.net/zhuyan/articles/138192.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于web.xml配置的详细说明</title><link>http://www.blogjava.net/zhuyan/articles/106763.html</link><dc:creator>朱岩</dc:creator><author>朱岩</author><pubDate>Tue, 27 Mar 2007 13:08:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyan/articles/106763.html</guid><wfw:comment>http://www.blogjava.net/zhuyan/comments/106763.html</wfw:comment><comments>http://www.blogjava.net/zhuyan/articles/106763.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyan/comments/commentRss/106763.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyan/services/trackbacks/106763.html</trackback:ping><description><![CDATA[form:javaresearch<br>1 定义头和根元素<br><br>部署描述符文件就像所有XML文件一样，必须以一个XML头开始。这个头声明可以使用的XML版本并给出文件的字符编码。<br>DOCYTPE声明必须立即出现在此头之后。这个声明告诉服务器适用的servlet规范的版本（如2.2或2.3）并指定管理此文件其余部分内容的语法的DTD(Document Type Definition，文档类型定义)。<br>所有部署描述符文件的顶层（根）元素为web-app。请注意，XML元素不像HTML，他们是大小写敏感的。因此，web-App和WEB-APP都是不合法的，web-app必须用小写。<br><br>2 部署描述符文件内的元素次序<br><br>XML 元素不仅是大小写敏感的，而且它们还对出现在其他元素中的次序敏感。例如，XML头必须是文件中的第一项，DOCTYPE声明必须是第二项，而web- app元素必须是第三项。在web-app元素内，元素的次序也很重要。服务器不一定强制要求这种次序，但它们允许（实际上有些服务器就是这样做的）完全拒绝执行含有次序不正确的元素的Web应用。这表示使用非标准元素次序的web.xml文件是不可移植的。<br>下面的列表给出了所有可直接出现在web-app元素内的合法元素所必需的次序。例如，此列表说明servlet元素必须出现在所有servlet-mapping元素之前。请注意，所有这些元素都是可选的。因此，可以省略掉某一元素，但不能把它放于不正确的位置。<br>l icon icon元素指出IDE和GUI工具用来表示Web应用的一个和两个图像文件的位置。<br>l display-name display-name元素提供GUI工具可能会用来标记这个特定的Web应用的一个名称。<br>l description description元素给出与此有关的说明性文本。<br>l context-param context-param元素声明应用范围内的初始化参数。<br>l filter 过滤器元素将一个名字与一个实现javax.servlet.Filter接口的类相关联。<br>l filter-mapping 一旦命名了一个过滤器，就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。<br>l listener servlet API的版本2.3增加了对事件监听程序的支持，事件监听程序在建立、修改和删除会话或servlet环境时得到通知。Listener元素指出事件监听程序类。<br>l servlet 在向servlet或JSP页面制定初始化参数或定制URL时，必须首先命名servlet或JSP页面。Servlet元素就是用来完成此项任务的。<br>l servlet-mapping 服务器一般为servlet提供一个缺省的URL：http://host/webAppPrefix/servlet/ServletName。但是，常常会更改这个URL，以便servlet可以访问初始化参数或更容易地处理相对URL。在更改缺省URL时，使用servlet-mapping元素。<br>l session -config 如果某个会话在一定时间内未被访问，服务器可以抛弃它以节省内存。可通过使用HttpSession的 setMaxInactiveInterval方法明确设置单个会话对象的超时值，或者可利用session-config元素制定缺省超时值。<br>l mime-mapping 如果Web应用具有想到特殊的文件，希望能保证给他们分配特定的MIME类型，则mime-mapping元素提供这种保证。<br>l welcom-file-list welcome-file-list元素指示服务器在收到引用一个目录名而不是文件名的URL时，使用哪个文件。<br>l error-page error-page元素使得在返回特定HTTP状态代码时，或者特定类型的异常被抛出时，能够制定将要显示的页面。<br>l taglib taglib元素对标记库描述符文件（Tag Libraryu Descriptor file）指定别名。此功能使你能够更改TLD文件的位置，而不用编辑使用这些文件的JSP页面。<br>l resource-env-ref resource-env-ref元素声明与资源相关的一个管理对象。<br>l resource-ref resource-ref元素声明一个资源工厂使用的外部资源。<br>l security-constraint security-constraint元素制定应该保护的URL。它与login-config元素联合使用<br>l login-config 用login-config元素来指定服务器应该怎样给试图访问受保护页面的用户授权。它与sercurity-constraint元素联合使用。<br>l security-role security-role元素给出安全角色的一个列表，这些角色将出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可使高级IDE处理安全信息更为容易。<br>l env-entry env-entry元素声明Web应用的环境项。<br>l ejb-ref ejb-ref元素声明一个EJB的主目录的引用。<br>l ejb-local-ref ejb-local-ref元素声明一个EJB的本地主目录的应用。<br><br>3 分配名称和定制的UL<br><br>在web.xml中完成的一个最常见的任务是对servlet或JSP页面给出名称和定制的URL。用servlet元素分配名称，使用servlet-mapping元素将定制的URL与刚分配的名称相关联。<br>3.1 分配名称<br>为了提供初始化参数，对servlet或JSP页面定义一个定制URL或分配一个安全角色，必须首先给servlet或JSP页面一个名称。可通过 servlet元素分配一个名称。最常见的格式包括servlet-name和servlet-class子元素（在web-app元素内），如下所示：<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br>&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br>&lt;/servlet&gt; <br>这表示位于WEB-INF/classes/moreservlets/TestServlet的servlet已经得到了注册名Test。给 servlet一个名称具有两个主要的含义。首先，初始化参数、定制的URL模式以及其他定制通过此注册名而不是类名引用此servlet。其次,可在 URL而不是类名中使用此名称。因此，利用刚才给出的定义，URL <a href="http://host/webAppPrefix/servlet/Test" target=_blank>http://host/webAppPrefix/servlet/Test</a> 可用于 <a href="http://host/webAppPrefix/servlet/moreservlets.TestServlet" target=_blank>http://host/webAppPrefix/servlet/moreservlets.TestServlet</a> 的场所。<br>请记住：XML元素不仅是大小写敏感的，而且定义它们的次序也很重要。例如，web-app元素内所有servlet元素必须位于所有servlet- mapping元素（下一小节介绍）之前，而且还要位于5.6节和5.11节讨论的与过滤器或文档相关的元素（如果有的话）之前。类似地， servlet 的servlet-name子元素也必须出现在servlet-class之前。5.2节"部署描述符文件内的元素次序"将详细介绍这种必需的次序。<br>例如，程序清单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时的结果。<br><br>程序清单5-1 TestServlet.java<br>package moreservlets;<br><br>import java.io.*;<br>import javax.servlet.*;<br>import javax.servlet.http.*;<br><br>/** Simple servlet used to illustrate servlet naming<br>* and custom URLs.<br>*
<p><br>* Taken from More Servlets and JavaServer Pages<br>* from Prentice Hall and Sun Microsystems Press,<br>* <a href="http://www.moreservlets.com/." target=_blank>http://www.moreservlets.com/.</a><br>* &#169; 2002 Marty Hall; may be freely used or adapted.<br>*/<br><br>public class TestServlet extends HttpServlet {<br>public void doGet(HttpServletRequest request,<br>HttpServletResponse response)<br>throws ServletException, IOException {<br>response.setContentType("text/html");<br>PrintWriter out = response.getWriter();<br>String uri = request.getRequestURI();<br>out.println(ServletUtilities.headWithTitle("Test Servlet") +<br>"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br>" </p>
<h2>URI: " + uri + "</h2>
\n" +<br>"&lt;/BODY&gt;&lt;/HTML&gt;");<br>}<br>}<br><br><br>程序清单5-2 web.xml（说明servlet名称的摘录）<br>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br>&lt;!DOCTYPE web-app<br>PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br>"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br><br>&lt;web-app&gt;<br>&lt;!-- &#8230; --&gt;<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br>&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br>&lt;/servlet&gt;<br>&lt;!-- &#8230; --&gt;<br>&lt;/web-app&gt;<br><br>3.2 定义定制的URL<br>大多数服务器具有一个缺省的serlvet URL：<br>http: //host/webAppPrefix/servlet/packageName.ServletName。虽然在开发中使用这个URL很方便，但是我们常常会希望另一个URL用于部署。例如，可能会需要一个出现在Web应用顶层的URL（如，http: //host/webAppPrefix/Anyname），并且在此URL中没有servlet项。位于顶层的URL简化了相对URL的使用。此外，对许多开发人员来说，顶层URL看上去比更长更麻烦的缺省URL更简短。<br>事实上，有时需要使用定制的URL。比如，你可能想关闭缺省URL映射，以便更好地强制实施安全限制或防止用户意外地访问无初始化参数的servlet。如果你禁止了缺省的URL，那么你怎样访问servlet呢？这时只有使用定制的URL了。<br>为了分配一个定制的URL，可使用servlet-mapping元素及其servlet-name和url-pattern子元素。Servlet- name元素提供了一个任意名称，可利用此名称引用相应的servlet；url-pattern描述了相对于Web应用的根目录的URL。url- pattern元素的值必须以斜杠（/）起始。<br>下面给出一个简单的web.xml摘录，它允许使用URL <a href="http://host/webAppPrefix/UrlTest而不是http://host/webAppPrefix/servlet/Test或" target=_blank>http://host/webAppPrefix/UrlTest而不是http://host/webAppPrefix/servlet/Test或</a><br>http: //host/webAppPrefix/servlet/moreservlets.TestServlet。请注意，仍然需要XML头、 DOCTYPE声明以及web-app封闭元素。此外，可回忆一下，XML元素出现地次序不是随意的。特别是，需要把所有servlet元素放在所有 servlet-mapping元素之前。<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br>&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br>&lt;/servlet&gt;<br>&lt;!-- ... --&gt;<br>&lt;servlet-mapping&gt;<br>&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br>&lt;url-pattern&gt;/UrlTest&lt;/url-pattern&gt;<br>&lt;/servlet-mapping&gt;<br>URL模式还可以包含通配符。例如，下面的小程序指示服务器发送所有以Web应用的URL前缀开始，以..asp结束的请求到名为BashMS的servlet。<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;BashMS&lt;/servlet-name&gt;<br>&lt;servlet-class&gt;msUtils.ASPTranslator&lt;/servlet-class&gt;<br>&lt;/servlet&gt;<br>&lt;!-- ... --&gt;<br>&lt;servlet-mapping&gt;<br>&lt;servlet-name&gt;BashMS&lt;/servlet-name&gt;<br>&lt;url-pattern&gt;/*.asp&lt;/url-pattern&gt;<br>&lt;/servlet-mapping&gt;<br>3.3 命名JSP页面<br>因为JSP页面要转换成sevlet，自然希望就像命名servlet一样命名JSP页面。毕竟，JSP页面可能会从初始化参数、安全设置或定制的URL中受益，正如普通的serlvet那样。虽然JSP页面的后台实际上是servlet这句话是正确的，但存在一个关键的猜疑：即，你不知道JSP页面的实际类名（因为系统自己挑选这个名字）。因此，为了命名JSP页面，可将jsp-file元素替换为servlet-calss元素，如下所示：<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br>&lt;jsp-file&gt;/TestPage.jsp&lt;/jsp-file&gt;<br>&lt;/servlet&gt;<br>命名JSP页面的原因与命名servlet的原因完全相同：即为了提供一个与定制设置（如，初始化参数和安全设置）一起使用的名称，并且，以便能更改激活 JSP页面的URL（比方说，以便多个URL通过相同页面得以处理，或者从URL中去掉.jsp扩展名）。但是，在设置初始化参数时，应该注意，JSP 页面是利用jspInit方法，而不是init方法读取初始化参数的。<br>例如，程序清单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）的一部分。<br><br>程序清单5-3 TestPage.jsp<br>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br>&lt;HTML&gt;<br>&lt;HEAD&gt;<br><br>&lt;/HEAD&gt;<br>&lt;BODY BGCOLOR="#FDF5E6"&gt;<br>
<h2>URI: &lt;%= request.getRequestURI() %&gt;</h2>
<br>&lt;/BODY&gt;<br>&lt;/HTML&gt;<br><br><br>程序清单5-4 web.xml（说明JSP页命名的摘录）<br>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br>&lt;!DOCTYPE web-app<br>PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br>"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br><br>&lt;web-app&gt;<br>&lt;!-- ... --&gt;<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br>&lt;jsp-file&gt;/TestPage.jsp&lt;/jsp-file&gt;<br>&lt;/servlet&gt;<br>&lt;!-- ... --&gt;<br>&lt;servlet-mapping&gt;<br>&lt;servlet-name&gt; PageName &lt;/servlet-name&gt;<br>&lt;url-pattern&gt;/UrlTest2/*&lt;/url-pattern&gt;<br>&lt;/servlet-mapping&gt;<br>&lt;!-- ... --&gt;<br>&lt;/web-app&gt;<br><br><br>4 禁止激活器servlet<br><br>对servlet 或JSP页面建立定制URL的一个原因是，这样做可以注册从 init（servlet）或jspInit（JSP页面）方法中读取得初始化参数。但是，初始化参数只在是利用定制URL模式或注册名访问 servlet或JSP页面时可以使用，用缺省URL http: //host/webAppPrefix/servlet/ServletName 访问时不能使用。因此，你可能会希望关闭缺省URL，这样就不会有人意外地调用初始化servlet了。这个过程有时称为禁止激活器servlet，因为多数服务器具有一个用缺省的servlet URL注册的标准 servlet，并激活缺省的URL应用的实际servlet。<br>有两种禁止此缺省URL的主要方法：<br>l 在每个Web应用中重新映射/servlet/模式。<br>l 全局关闭激活器servlet。<br>重要的是应该注意到，虽然重新映射每个Web应用中的/servlet/模式比彻底禁止激活servlet所做的工作更多，但重新映射可以用一种完全可移植的方式来完成。相反，全局禁止激活器servlet完全是针对具体机器的，事实上有的服务器（如ServletExec）没有这样的选择。下面的讨论对每个Web应用重新映射/servlet/ URL模式的策略。后面提供在Tomcat中全局禁止激活器servlet的详细内容。<br>4.1 重新映射/servlet/URL模式<br>在一个特定的Web应用中禁止以http://host/webAppPrefix/servlet/ 开始的URL的处理非常简单。所需做的事情就是建立一个错误消息servlet，并使用前一节讨论的url-pattern元素将所有匹配请求转向该 servlet。只要简单地使用：<br>&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br>作为servlet-mapping元素中的模式即可。<br>例如，程序清单5-5给出了将SorryServlet servlet（程序清单5-6）与所有以http://host/webAppPrefix/servlet/ 开头的URL相关联的部署描述符文件的一部分。<br><br>程序清单5-5 web.xml（说明JSP页命名的摘录）<br>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br>&lt;!DOCTYPE web-app<br>PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br>"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br><br>&lt;web-app&gt;<br>&lt;!-- ... --&gt;<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;Sorry&lt;/servlet-name&gt;<br>&lt;servlet-class&gt;moreservlets.SorryServlet&lt;/servlet-class&gt;<br>&lt;/servlet&gt;<br>&lt;!-- ... --&gt;<br>&lt;servlet-mapping&gt;<br>&lt;servlet-name&gt; Sorry &lt;/servlet-name&gt;<br>&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br>&lt;/servlet-mapping&gt;<br>&lt;!-- ... --&gt;<br>&lt;/web-app&gt;<br><br><br>程序清单5-6 SorryServlet.java<br>package moreservlets;<br><br>import java.io.*;<br>import javax.servlet.*;<br>import javax.servlet.http.*;<br><br>/** Simple servlet used to give error messages to<br>* users who try to access default servlet URLs<br>* (i.e., <a href="http://host/webAppPrefix/servlet/ServletName)" target=_blank>http://host/webAppPrefix/servlet/ServletName)</a><br>* in Web applications that have disabled this<br>* behavior.<br>*
<p><br>* Taken from More Servlets and JavaServer Pages<br>* from Prentice Hall and Sun Microsystems Press,<br>* <a href="http://www.moreservlets.com/." target=_blank>http://www.moreservlets.com/.</a><br>* &#169; 2002 Marty Hall; may be freely used or adapted.<br>*/<br><br>public class SorryServlet extends HttpServlet {<br>public void doGet(HttpServletRequest request,<br>HttpServletResponse response)<br>throws ServletException, IOException {<br>response.setContentType("text/html");<br>PrintWriter out = response.getWriter();<br>String title = "Invoker Servlet Disabled.";<br>out.println(ServletUtilities.headWithTitle(title) +<br>"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br>" </p>
<h2>" + title + "</h2>
\n" +<br>"Sorry, access to servlets by means of\n" +<br>"URLs that begin with\n" +<br>"http://host/webAppPrefix/servlet/\n" +<br>"has been disabled.\n" + <br>"&lt;/BODY&gt;&lt;/HTML&gt;");<br>}<br><br>public void doPost(HttpServletRequest request,<br>HttpServletResponse response)<br>throws ServletException, IOException {<br>doGet(request, response);<br>}<br>}<br><br><br>4.2 全局禁止激活器：Tomcat<br>Tomcat 4中用来关闭缺省URL的方法与Tomcat 3中所用的很不相同。下面介绍这两种方法：<br>1．禁止激活器： Tomcat 4<br>Tomcat 4 用与前面相同的方法关闭激活器servlet，即利用web.xml中的url-mapping元素进行关闭。不同之处在于Tomcat使用了放在 install_dir/conf中的一个服务器专用的全局web.xml文件，而前面使用的是存放在每个Web应用的WEB-INF目录中的标准 web.xml文件。<br>因此，为了在Tomcat 4中关闭激活器servlet，只需在install_dir/conf/web.xml中简单地注释出/servlet/* URL映射项即可，如下所示：<br>&lt;!-- <br>&lt;servlet-mapping&gt;<br>&lt;servlet-name&gt;invoker&lt;/servlet-name&gt;<br>&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br>&lt;/servlet-mapping&gt;<br>--&gt;<br>再次提醒，应该注意这个项是位于存放在install_dir/conf的Tomcat专用的web.xml文件中的，此文件不是存放在每个Web应用的WEB-INF目录中的标准web.xml。<br>2．禁止激活器：Tomcat3<br>在Apache Tomcat 的版本3中，通过在install_dir/conf/server.xml中注释出InvokerInterceptor项全局禁止缺省 servlet URL。例如，下面是禁止使用缺省servlet URL的server.xml文件的一部分。<br>&lt;!-- <br>&lt;RequsetInterceptor <br>className="org.apache.tomcat.request.InvokerInterceptor"<br>debug="0" prefix="/servlet/" /&gt;<br>--&gt;<br><br>5 初始化和预装载servlet与JSP页面<br><br>这里讨论控制servlet和JSP页面的启动行为的方法。特别是，说明了怎样分配初始化参数以及怎样更改服务器生存期中装载servlet和JSP页面的时刻。<br>5.1 分配servlet初始化参数<br>利用init-param元素向servlet提供初始化参数，init-param元素具有param-name和param-value子元素。例如，在下面的例子中，如果initServlet servlet是利用它的注册名（InitTest）访问的，它将能够从其方法中调用 getServletConfig(). getInitParameter("param1")获得"Value 1"，调用 getServletConfig().getInitParameter("param2")获得"2"。<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;InitTest&lt;/servlet-name&gt;<br>&lt;servlet-class&gt;moreservlets.InitServlet&lt;/servlet-class&gt;<br>&lt;init-param&gt;<br>&lt;param-name&gt;param1&lt;/param-name&gt;<br>&lt;param-value&gt;value1&lt;/param-value&gt;<br>&lt;/init-param&gt;<br>&lt;init-param&gt;<br>&lt;param-name&gt;param2&lt;/param-name&gt;<br>&lt;param-value&gt;2&lt;/param-value&gt;<br>&lt;/init-param&gt;<br>&lt;/servlet&gt;<br>在涉及初始化参数时，有几点需要注意：<br>l 返回值。GetInitParameter的返回值总是一个String。因此，在前一个例子中，可对param2使用Integer.parseInt获得一个int。<br>l JSP中的初始化。JSP页面使用jspInit而不是init。JSP页面还需要使用jsp-file元素代替servlet-class。<br>l 缺省URL。初始化参数只在通过它们的注册名或与它们注册名相关的定制URL模式访问Servlet时可以使用。因此，在这个例子中，param1和 param2初始化参数将能够在使用URL <a href="http://host/webAppPrefix/servlet/InitTest" target=_blank>http://host/webAppPrefix/servlet/InitTest</a> 时可用，但在使用 URL <a href="http://host/webAppPrefix/servlet/myPackage.InitServlet" target=_blank>http://host/webAppPrefix/servlet/myPackage.InitServlet</a> 时不能使用。<br>例如，程序清单5-7给出一个名为InitServlet的简单servlet，它使用init方法设置firstName和emailAddress字段。程序清单5-8给出分配名称InitTest给servlet的web.xml文件。<br>程序清单5-7 InitServlet.java<br>package moreservlets;<br><br>import java.io.*;<br>import javax.servlet.*;<br>import javax.servlet.http.*;<br><br>/** Simple servlet used to illustrate servlet<br>* initialization parameters.<br>*
<p><br>* Taken from More Servlets and JavaServer Pages<br>* from Prentice Hall and Sun Microsystems Press,<br>* <a href="http://www.moreservlets.com/." target=_blank>http://www.moreservlets.com/.</a><br>* &#169; 2002 Marty Hall; may be freely used or adapted.<br>*/<br><br>public class InitServlet extends HttpServlet {<br>private String firstName, emailAddress;<br><br>public void init() {<br>ServletConfig config = getServletConfig();<br>firstName = config.getInitParameter("firstName");<br>emailAddress = config.getInitParameter("emailAddress");<br>}<br><br>public void doGet(HttpServletRequest request,<br>HttpServletResponse response)<br>throws ServletException, IOException {<br>response.setContentType("text/html");<br>PrintWriter out = response.getWriter();<br>String uri = request.getRequestURI();<br>out.println(ServletUtilities.headWithTitle("Init Servlet") +<br>"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br>" </p>
<h2>Init Parameters:</h2>
\n" +<br>"
<ul>\n" +<br>"
    <li>First name: " + firstName + "\n" +<br>"
    <li>Email address: " + emailAddress + "\n" +<br>"</li>
</ul>
\n" + <br>"&lt;/BODY&gt;&lt;/HTML&gt;");<br>}<br>}<br><br><br>程序清单5-8 web.xml（说明初始化参数的摘录）<br>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br>&lt;!DOCTYPE web-app<br>PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br>"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br><br>&lt;web-app&gt;<br>&lt;!-- ... --&gt;<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;InitTest&lt;/servlet-name&gt;<br>&lt;servlet-class&gt;moreservlets.InitServlet&lt;/servlet-class&gt;<br>&lt;init-param&gt;<br>&lt;param-name&gt;firstName&lt;/param-name&gt;<br>&lt;param-value&gt;Larry&lt;/param-value&gt;<br>&lt;/init-param&gt;<br>&lt;init-param&gt;<br>&lt;param-name&gt;emailAddress&lt;/param-name&gt;<br>&lt;param-value&gt;Ellison@Microsoft.com&lt;/param-value&gt;<br>&lt;/init-param&gt;<br>&lt;/servlet&gt;<br>&lt;!-- ... --&gt;<br>&lt;/web-app&gt;<br><br>5.2 分配JSP初始化参数<br>给JSP页面提供初始化参数在三个方面不同于给servlet提供初始化参数。<br>1）使用jsp-file而不是servlet-class。因此，WEB-INF/web.xml文件的servlet元素如下所示：<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br>&lt;jsp-file&gt;/RealPage.jsp&lt;/jsp-file&gt;<br>&lt;init-param&gt;<br>&lt;param-name&gt;...&lt;/param-name&gt;<br>&lt;param-value&gt;...&lt;/param-value&gt;<br>&lt;/init-param&gt;<br>...<br>&lt;/servlet&gt;<br>2) 几乎总是分配一个明确的URL模式。对servlet，一般相应地使用以http://host/webAppPrefix/servlet/ 开始的缺省URL。只需记住，使用注册名而不是原名称即可。这对于JSP页面在技术上也是合法的。例如，在上面给出的例子中，可用URL http: //host/webAppPrefix/servlet/PageName 访问RealPage.jsp的对初始化参数具有访问权的版本。但在用于 JSP页面时，许多用户似乎不喜欢应用常规的servlet的URL。此外，如果 JSP页面位于服务器为其提供了目录清单的目录中（如，一个既没有 index.html也没有index.jsp文件的目录），则用户可能会连接到此 JSP页面，单击它，从而意外地激活未初始化的页面。因此，好的办法是使用url-pattern（5.3节）将JSP页面的原URL与注册的 servlet名相关联。这样，客户机可使用JSP页面的普通名称，但仍然激活定制的版本。例如，给定来自项目1的servlet定义，可使用下面的 servlet-mapping定义：<br>&lt;servlet-mapping&gt;<br>&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br>&lt;url-pattern&gt;/RealPage.jsp&lt;/url-pattern&gt;<br>&lt;/servlet-mapping&gt;<br>3）JSP页使用jspInit而不是init。自动从JSP页面建立的servlet或许已经使用了inti方法。因此，使用JSP声明提供一个init方法是不合法的，必须制定jspInit方法。<br>为了说明初始化JSP页面的过程，程序清单5-9给出了一个名为InitPage.jsp的JSP页面，它包含一个jspInit方法且放置于 deployDemo Web应用层次结构的顶层。一般，http://host/deployDemo/InitPage.jsp 形式的URL将激活此页面的不具有初始化参数访问权的版本，从而将对firstName和emailAddress变量显示null。但是， web.xml文件（程序清单5-10）分配了一个注册名，然后将该注册名与URL模式/InitPage.jsp相关联。<br><br>程序清单5-9 InitPage.jsp<br>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br>&lt;HTML&gt;<br>&lt;HEAD&gt;&lt;/HEAD&gt;<br>&lt;BODY BGCOLOR="#FDF5E6"&gt;<br>
<h2>Init Parameters:</h2>
<br>
<ul><br>
    <li>First name: &lt;%= firstName %&gt;<br>
    <li>Email address: &lt;%= emailAddress %&gt;<br></li>
</ul>
<br>&lt;/BODY&gt;&lt;/HTML&gt;<br>&lt;%!<br>private String firstName, emailAddress;<br><br>public void jspInit() {<br>ServletConfig config = getServletConfig();<br>firstName = config.getInitParameter("firstName");<br>emailAddress = config.getInitParameter("emailAddress");<br>}<br>%&gt;<br><br><br>程序清单5-10 web.xml（说明JSP页面的init参数的摘录）<br>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br>&lt;!DOCTYPE web-app<br>PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br>"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br><br>&lt;web-app&gt;<br>&lt;!-- ... --&gt;<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;InitPage&lt;/servlet-name&gt;<br>&lt;jsp-file&gt;/InitPage.jsp&lt;/jsp-file&gt;<br>&lt;init-param&gt;<br>&lt;param-name&gt;firstName&lt;/param-name&gt;<br>&lt;param-value&gt;Bill&lt;/param-value&gt;<br>&lt;/init-param&gt;<br>&lt;init-param&gt;<br>&lt;param-name&gt;emailAddress&lt;/param-name&gt;<br>&lt;param-value&gt;gates@oracle.com&lt;/param-value&gt;<br>&lt;/init-param&gt;<br>&lt;/servlet&gt;<br>&lt;!-- ... --&gt; <br>&lt;servlet-mapping&gt;<br>&lt;servlet-name&gt; InitPage&lt;/servlet-name&gt;<br>&lt;url-pattern&gt;/InitPage.jsp&lt;/url-pattern&gt;<br>&lt;/servlet-mapping&gt;<br>&lt;!-- ... --&gt;<br>&lt;/web-app&gt;<br><br><br>5.3 提供应用范围内的初始化参数<br>一般，对单个地servlet或JSP页面分配初始化参数。指定的servlet或JSP页面利用ServletConfig的 getInitParameter方法读取这些参数。但是，在某些情形下，希望提供可由任意servlet或JSP页面借助ServletContext 的getInitParameter方法读取的系统范围内的初始化参数。<br>可利用context-param元素声明这些系统范围内的初始化值。context-param元素应该包含param-name、param-value以及可选的description子元素，如下所示：<br>&lt;context-param&gt;<br>&lt;param-name&gt;support-email&lt;/param-name&gt;<br>&lt;param-value&gt;blackhole@mycompany.com&lt;/param-value&gt;<br>&lt;/context-param&gt;<br>可回忆一下，为了保证可移植性，web.xml内的元素必须以正确的次序声明。但这里应该注意，context-param元素必须出现任意与文档有关的元素（icon、display-name或description）之后及filter、filter-mapping、listener或 servlet元素之前。<br>5.4 在服务器启动时装载servlet<br>假如servlet或JSP页面有一个要花很长时间执行的 init （servlet）或jspInit（JSP）方法。例如，假如init或jspInit方法从某个数据库或ResourceBundle查找产量。这种情况下，在第一个客户机请求时装载servlet的缺省行为将对第一个客户机产生较长时间的延迟。因此，可利用servlet的load-on - startup元素规定服务器在第一次启动时装载servlet。下面是一个例子。<br>&lt;servlet&gt;<br>&lt;servlet-name&gt; &#8230; &lt;/servlet-name&gt;<br>&lt;servlet-class&gt; &#8230; &lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br>&lt;load-on-startup/&gt;<br>&lt;/servlet&gt;<br>可以为此元素体提供一个整数而不是使用一个空的load-on-startup。想法是服务器应该在装载较大数目的servlet或JSP页面之前装载较少数目的servlet或JSP页面。例如，下面的servlet项（放置在Web应用的WEB-INF目录下的web.xml文件中的web-app元素内）将指示服务器首先装载和初始化SearchServlet，然后装载和初始化由位于Web应用的result目录中的index.jsp文件产生的 servlet。<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;Search&lt;/servlet-name&gt;<br>&lt;servlet-class&gt;myPackage.SearchServlet&lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br>&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br>&lt;/servlet&gt;<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;Results&lt;/servlet-name&gt;<br>&lt;servlet-class&gt;/results/index.jsp&lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br>&lt;load-on-startup&gt;2&lt;/load-on-startup&gt;<br>&lt;/servlet&gt;<br><br>6 声明过滤器<br><br>servlet版本2.3引入了过滤器的概念。虽然所有支持servlet API版本2.3的服务器都支持过滤器，但为了使用与过滤器有关的元素，必须在web.xml中使用版本2.3的DTD。<br>过滤器可截取和修改进入一个servlet或JSP页面的请求或从一个servlet或JSP页面发出的相应。在执行一个servlet或JSP页面之前，必须执行第一个相关的过滤器的doFilter方法。在该过滤器对其FilterChain对象调用doFilter时，执行链中的下一个过滤器。如果没有其他过滤器，servlet或JSP页面被执行。过滤器具有对到来的ServletRequest对象的全部访问权，因此，它们可以查看客户机名、查找到来的cookie等。为了访问servlet或JSP页面的输出，过滤器可将响应对象包裹在一个替身对象（stand-in object）中，比方说把输出累加到一个缓冲区。在调用FilterChain对象的doFilter方法之后，过滤器可检查缓冲区，如有必要，就对它进行修改，然后传送到客户机。<br>例如，程序清单5-11帝国难以了一个简单的过滤器，只要访问相关的servlet或JSP页面，它就截取请求并在标准输出上打印一个报告（开发过程中在桌面系统上运行时，大多数服务器都可以使用这个过滤器）。<br><br>程序清单5-11 ReportFilter.java<br>package moreservlets;<br><br>import java.io.*;<br>import javax.servlet.*;<br>import javax.servlet.http.*;<br>import java.util.*;<br><br>/** Simple filter that prints a report on the standard output <br>* whenever the associated servlet or JSP page is accessed.<br>*
<p><br>* Taken from More Servlets and JavaServer Pages<br>* from Prentice Hall and Sun Microsystems Press,<br>* <a href="http://www.moreservlets.com/." target=_blank>http://www.moreservlets.com/.</a><br>* &#169; 2002 Marty Hall; may be freely used or adapted.<br>*/<br><br>public class ReportFilter implements Filter {<br>public void doFilter(ServletRequest request,<br>ServletResponse response,<br>FilterChain chain)<br>throws ServletException, IOException {<br>HttpServletRequest req = (HttpServletRequest)request;<br>System.out.println(req.getRemoteHost() +<br>" tried to access " +<br>req.getRequestURL() +<br>" on " + new Date() + ".");<br>chain.doFilter(request,response);<br>}<br><br>public void init(FilterConfig config)<br>throws ServletException {<br>}<br><br>public void destroy() {}<br>}<br><br>一旦建立了一个过滤器，可以在web.xml中利用filter元素以及filter-name（任意名称）、file-class（完全限定的类名）和（可选的）init-params子元素声明它。请注意，元素在web.xml的web-app元素中出现的次序不是任意的；允许服务器（但不是必需的）强制所需的次序，并且实际中有些服务器也是这样做的。但这里要注意，所有filter元素必须出现在任意filter-mapping元素之前， filter-mapping元素又必须出现在所有servlet或servlet-mapping元素之前。<br>例如，给定上述的ReportFilter类，可在web.xml中作出下面的filter声明。它把名称Reporter与实际的类ReportFilter（位于moreservlets程序包中）相关联。<br>&lt;filter&gt;<br>&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br>&lt;filter-class&gt;moresevlets.ReportFilter&lt;/filter-class&gt;<br>&lt;/filter&gt;<br>一旦命名了一个过滤器，可利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。关于此项工作有两种选择。<br>首先，可使用filter-name和servlet-name子元素把此过滤器与一个特定的servlet名（此servlet名必须稍后在相同的 web.xml文件中使用servlet元素声明）关联。例如，下面的程序片断指示系统只要利用一个定制的URL访问名为 SomeServletName 的servlet或JSP页面，就运行名为Reporter的过滤器。<br>&lt;filter-mapping&gt;<br>&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br>&lt;servlet-name&gt;SomeServletName&lt;/servlet-name&gt;<br>&lt;/filter-mapping&gt;<br>其次，可利用filter-name和url-pattern子元素将过滤器与一组servlet、JSP页面或静态内容相关联。例如，相面的程序片段指示系统只要访问Web应用中的任意URL，就运行名为Reporter的过滤器。<br>&lt;filter-mapping&gt;<br>&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br>&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br>&lt;/filter-mapping&gt;<br>例如，程序清单5-12给出了将ReportFilter过滤器与名为PageName的servlet相关联的web.xml文件的一部分。名字 PageName依次又与一个名为TestPage.jsp的JSP页面以及以模式http: //host/webAppPrefix/UrlTest2/ 开头的URL相关联。TestPage.jsp的源代码已经JSP页面命名的谈论在前面的3节"分配名称和定制的URL"中给出。事实上，程序清单5- 12中的servlet和servlet-name项从该节原封不动地拿过来的。给定这些web.xml项，可看到下面的标准输出形式的调试报告（换行是为了容易阅读）。<br>audit.irs.gov tried to access <br><a href="http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html" target=_blank>http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html</a><br>on Tue Dec 25 13:12:29 EDT 2001.<br><br>程序清单5-12 Web.xml（说明filter用法的摘录）<br>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br>&lt;!DOCTYPE web-app<br>PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br>"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br><br>&lt;web-app&gt;<br>&lt;filter&gt;<br>&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br>&lt;filter-class&gt;moresevlets.ReportFilter&lt;/filter-class&gt;<br>&lt;/filter&gt;<br>&lt;!-- ... --&gt;<br>&lt;filter-mapping&gt;<br>&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br>&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br>&lt;/filter-mapping&gt;<br>&lt;!-- ... --&gt;<br>&lt;servlet&gt;<br>&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br>&lt;jsp-file&gt;/RealPage.jsp&lt;/jsp-file&gt;<br>&lt;/servlet&gt;<br>&lt;!-- ... --&gt;<br>&lt;servlet-mapping&gt;<br>&lt;servlet-name&gt; PageName &lt;/servlet-name&gt;<br>&lt;url-pattern&gt;/UrlTest2/*&lt;/url-pattern&gt;<br>&lt;/servlet-mapping&gt;<br>&lt;!-- ... --&gt;<br>&lt;/web-app&gt;<br><br><br>7 指定欢迎页<br><br>假如用户提供了一个像http: //host/webAppPrefix/directoryName/ 这样的包含一个目录名但没有包含文件名的 URL，会发生什么事情呢？用户能得到一个目录表？一个错误？还是标准文件的内容？如果得到标准文件内容，是 index.html、 index.jsp、default.html、default.htm或别的什么东西呢？<br>Welcome-file-list 元素及其辅助的 welcome-file元素解决了这个模糊的问题。例如，下面的web.xml项指出，如果一个URL给出一个目录名但未给出文件名，服务器应该首先试用index.jsp，然后再试用index.html。如果两者都没有找到，则结果有赖于所用的服务器（如一个目录列表）。<br>&lt;welcome-file-list&gt;<br>&lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;<br>&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;<br>&lt;/welcome-file-list&gt;<br>虽然许多服务器缺省遵循这种行为，但不一定必须这样。因此，明确地使用welcom-file-list保证可移植性是一种良好的习惯。<br><br>8 指定处理错误的页面<br><br>现在我了解到，你在开发servlet和JSP页面时从不会犯错误，而且你的所有页面是那样的清晰，一般的程序员都不会被它们的搞糊涂。但是，是人总会犯错误的，用户可能会提供不合规定的参数，使用不正确的URL或者不能提供必需的表单字段值。除此之外，其它开发人员可能不那么细心，他们应该有些工具来克服自己的不足。<br>error-page元素就是用来克服这些问题的。它有两个可能的子元素，分别是：error-code和exception- type。第一个子元素error-code指出在给定的HTTP错误代码出现时使用的URL。第二个子元素excpetion-type指出在出现某个给定的Java异常但未捕捉到时使用的URL。error-code和exception-type都利用location元素指出相应的URL。此 URL必须以/开始。location所指出的位置处的页面可通过查找HttpServletRequest对象的两个专门的属性来访问关于错误的信息，这两个属性分别是：javax.servlet.error.status_code和javax.servlet.error.message。<br>可回忆一下，在web.xml内以正确的次序声明web-app的子元素很重要。这里只要记住，error-page出现在web.xml文件的末尾附近，servlet、servlet-name和welcome-file-list之后即可。<br><br>8.1 error-code元素<br>为了更好地了解error-code元素的值，可考虑一下如果不正确地输入文件名，大多数站点会作出什么反映。这样做一般会出现一个404错误信息，它表示不能找到该文件，但几乎没提供更多有用的信息。另一方面，可以试一下在www.microsoft.com、www.ibm.com 处或者特别是在 www.bea.com 处输出未知的文件名。这是会得出有用的消息，这些消息提供可选择的位置，以便查找感兴趣的页面。提供这样有用的错误页面对于 Web应用来说是很有价值得。事实上rm-error-page子元素）。由form-login-page给出的HTML表单必须具有一个 j_security_check的 ACTION属性、一个名为j_username的用户名文本字段以及一个名为j_password的口令字段。<br>例如，程序清单5-19指示服务器使用基于表单的验证。Web应用的顶层目录中的一个名为login.jsp的页面将收集用户名和口令，并且失败的登陆将由相同目录中名为login-error.jsp的页面报告。<br><br>程序清单5-19 web.xml（说明login-config的摘录）<br>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br>&lt;!DOCTYPE web-app<br>PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br>"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br><br>&lt;web-app&gt;<br>&lt;!-- ... --&gt;<br>&lt;security-constraint&gt; ... &lt;/security-constraint&gt;<br>&lt;login-config&gt;<br>&lt;auth-method&gt; FORM &lt;/auth-method&gt;<br>&lt;form-login-config&gt;<br>&lt;form-login-page&gt;/login.jsp&lt;/form-login-page&gt;<br>&lt;form-error-page&gt;/login-error.jsp&lt;/form-error-page&gt;<br>&lt;/form-login-config&gt;<br>&lt;/login-config&gt;<br>&lt;!-- ... --&gt;<br>&lt;/web-app&gt;<br><br><br>9.2 限制对Web资源的访问<br>现在，可以指示服务器使用何种验证方法了。"了不起，"你说道，"除非我能指定一个来收到保护的 URL，否则没有多大用处。"没错。指出这些URL并说明他们应该得到何种保护正是security-constriaint元素的用途。此元素在 web.xml中应该出现在login-config的紧前面。它包含是个可能的子元素，分别是：web-resource-collection、 auth-constraint、user-data- constraint和display-name。下面各小节对它们进行介绍。<br>l web-resource-collection<br>此元素确定应该保护的资源。所有security-constraint元素都必须包含至少一个web-resource-collection项。此元素由一个给出任意标识名称的web-resource-name元素、一个确定应该保护的URL的url-pattern元素、一个指出此保护所适用的 HTTP命令（GET、POST等，缺省为所有方法）的http-method元素和一个提供资料的可选description元素组成。例如，下面的 Web-resource-collection项（在security-constratint元素内）指出Web应用的proprietary目录中所有文档应该受到保护。<br>&lt;security-constraint&gt;<br>&lt;web-resource-coolection&gt;<br>&lt;web-resource-name&gt;Proprietary&lt;/web-resource-name&gt;<br>&lt;url-pattern&gt;/propritary/*&lt;/url-pattern&gt;<br>&lt;/web-resource-coolection&gt;<br>&lt;!-- ... --&gt;<br>&lt;/security-constraint&gt;<br>重要的是应该注意到，url-pattern仅适用于直接访问这些资源的客户机。特别是，它不适合于通过MVC体系结构利用 RequestDispatcher来访问的页面，或者不适合于利用类似jsp:forward的手段来访问的页面。这种不匀称如果利用得当的话很有好处。例如，servlet可利用MVC体系结构查找数据，把它放到bean中，发送请求到从bean中提取数据的JSP页面并显示它。我们希望保证决不直接访问受保护的JSP页面，而只是通过建立该页面将使用的bean的servlet来访问它。url-pattern和auth-contraint元素可通过声明不允许任何用户直接访问JSP页面来提供这种保证。但是，这种不匀称的行为可能让开发人员放松警惕，使他们偶然对应受保护的资源提供不受限制的访问。 <br>l auth-constraint<br>尽管web-resource-collention元素质出了哪些URL应该受到保护，但是auth-constraint元素却指出哪些用户应该具有受保护资源的访问权。此元素应该包含一个或多个标识具有访问权限的用户类别role- name元素，以及包含（可选）一个描述角色的description元素。例如，下面web.xml中的security-constraint元素部门规定只有指定为Administrator或Big Kahuna（或两者）的用户具有指定资源的访问权。<br>&lt;security-constraint&gt;<br>&lt;web-resource-coolection&gt; ... &lt;/web-resource-coolection&gt;<br>&lt;auth-constraint&gt;<br>&lt;role-name&gt;administrator&lt;/role-name&gt;<br>&lt;role-name&gt;kahuna&lt;/role-name&gt;<br>&lt;/auth-constraint&gt;<br>&lt;/security-constraint&gt;<br>重要的是认识到，到此为止，这个过程的可移植部分结束了。服务器怎样确定哪些用户处于任何角色以及它怎样存放用户的口令，完全有赖于具体的系统。<br>例如，Tomcat使用install_dir/conf/tomcat-users.xml将用户名与角色名和口令相关联，正如下面例子中所示，它指出用户joe（口令bigshot）和jane（口令enaj）属于administrator和kahuna角色。<br>&lt;tomcat-users&gt;<br>&lt;user name="joe" password="bigshot" roles="administrator,kahuna" /&gt;<br>&lt;user name="jane" password="enaj" roles="kahuna" /&gt;<br>&lt;/tomcat-users&gt;<br>l user-data-constraint<br>这个可选的元素指出在访问相关资源时使用任何传输层保护。它必须包含一个transport-guarantee子元素（合法值为NONE、 INTEGRAL或CONFIDENTIAL），并且可选地包含一个description元素。transport-guarantee为NONE值将对所用的通讯协议不加限制。INTEGRAL值表示数据必须以一种防止截取它的人阅读它的方式传送。虽然原理上（并且在未来的HTTP版本中），在 INTEGRAL和CONFIDENTIAL之间可能会有差别，但在当前实践中，他们都只是简单地要求用SSL。例如，下面指示服务器只允许对相关资源做 HTTPS连接：<br>&lt;security-constraint&gt;<br>&lt;!-- ... --&gt;<br>&lt;user-data-constraint&gt;<br>&lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;<br>&lt;/user-data-constraint&gt;<br>&lt;/security-constraint&gt;<br>l display-name<br>security-constraint的这个很少使用的子元素给予可能由GUI工具使用的安全约束项一个名称。<br>9.3 分配角色名<br>迄今为止，讨论已经集中到完全由容器（服务器）处理的安全问题之上了。但servlet以及JSP页面也能够处理它们自己的安全问题。<br>例如，容器可能允许用户从bigwig或bigcheese角色访问一个显示主管人员额外紧贴的页面，但只允许bigwig用户修改此页面的参数。完成这种更细致的控制的一种常见方法是调用HttpServletRequset的isUserInRole方法，并据此修改访问。<br>Servlet的 security-role-ref子元素提供出现在服务器专用口令文件中的安全角色名的一个别名。例如，假如编写了一个调用 request.isUserInRole（"boss"）的servlet，但后来该servlet被用在了一个其口令文件调用角色manager而不是boss的服务器中。下面的程序段使该servlet能够使用这两个名称中的任何一个。<br>&lt;servlet&gt;<br>&lt;!-- ... --&gt;<br>&lt;security-role-ref&gt;<br>&lt;role-name&gt;boss&lt;/role-name&gt; &lt;!-- New alias --&gt;<br>&lt;role-link&gt;manager&lt;/role-link&gt; &lt;!-- Real name --&gt;<br>&lt;/security-role-ref&gt;<br>&lt;/servlet&gt;<br>也可以在web-app内利用security-role元素提供将出现在role-name元素中的所有安全角色的一个全局列表。分别地生命角色使高级IDE容易处理安全信息。<br><br>10 控制会话超时<br><br>如果某个会话在一定的时间内未被访问，服务器可把它扔掉以节约内存。可利用HttpSession的setMaxInactiveInterval方法直接设置个别会话对象的超时值。如果不采用这种方法，则缺省的超时值由具体的服务器决定。但可利用session-config和session- timeout元素来给出一个适用于所有服务器的明确的超时值。超时值的单位为分钟，因此，下面的例子设置缺省会话超时值为三个小时（180分钟）。<br>&lt;session-config&gt;<br>&lt;session-timeout&gt;180&lt;/session-timeout&gt;<br>&lt;/session-config&gt;<br><br>11 Web应用的文档化<br><br>越来越多的开发环境开始提供servlet和JSP的直接支持。例子有Borland Jbuilder Enterprise Edition、 Macromedia UltraDev、Allaire JRun Studio（写此文时，已被Macromedia收购）以及 IBM VisuaAge for Java等。<br>大量的web.xml元素不仅是为服务器设计的，而且还是为可视开发环境设计的。它们包括icon、display-name和discription等。<br>可回忆一下，在web.xml内以适当地次序声明web-app子元素很重要。不过，这里只要记住icon、display-name和description是web.xml的web-app元素内的前三个合法元素即可。<br>l icon<br>icon元素指出GUI工具可用来代表Web应用的一个和两个图像文件。可利用small-icon元素指定一幅16 x 16的GIF或JPEG图像，用large-icon元素指定一幅32 x 32的图像。下面举一个例子： <br>&lt;icon&gt;<br>&lt;small-icon&gt;/images/small-book.gif&lt;/small-icon&gt;<br>&lt;large-icon&gt;/images/tome.jpg&lt;/large-icon&gt;<br>&lt;/icon&gt;<br>l display-name<br>display-name元素提供GUI工具可能会用来标记此Web应用的一个名称。下面是个例子。<br>&lt;display-name&gt;Rare Books&lt;/display-name&gt;<br>l description<br>description元素提供解释性文本，如下所示：<br>&lt;description&gt;<br>This Web application represents the store developed for<br>rare-books.com, an online bookstore specializing in rare<br>and limited-edition books.<br>&lt;/description&gt;<br><br>12 关联文件与MIME类型<br><br>服务器一般都具有一种让Web站点管理员将文件扩展名与媒体相关联的方法。例如，将会自动给予名为mom.jpg的文件一个image/jpeg的 MIME 类型。但是，假如你的Web应用具有几个不寻常的文件，你希望保证它们在发送到客户机时分配为某种MIME类型。mime-mapping元素（具有 extension和mime-type子元素）可提供这种保证。例如，下面的代码指示服务器将application/x-fubar的 MIME类型分配给所有以.foo结尾的文件。<br>&lt;mime-mapping&gt;<br>&lt;extension&gt;foo&lt;/extension&gt;<br>&lt;mime-type&gt;application/x-fubar&lt;/mime-type&gt;<br>&lt;/mime-mapping&gt;<br>或许，你的Web应用希望重载（override）标准的映射。例如，下面的代码将告诉服务器在发送到客户机时指定.ps文件作为纯文本（text/plain）而不是作为PostScript（application/postscript）。<br>&lt;mime-mapping&gt;<br>&lt;extension&gt;ps&lt;/extension&gt;<br>&lt;mime-type&gt;application/postscript&lt;/mime-type&gt;<br>&lt;/mime-mapping&gt;<br><br><br>13 定位TLD<br><br>JSP taglib 元素具有一个必要的uri属性，它给出一个TLD（Tag Library Descriptor）文件相对于Web应用的根的位置。TLD文件的实际名称在发布新的标签库版本时可能会改变，但我们希望避免更改所有现有JSP页面。此外，可能还希望使用保持taglib元素的简练性的一个简短的uri。这就是部署描述符文件的taglib元素派用场的所在了。Taglib包含两个子元素：taglib-uri和taglib-location。 taglib-uri元素应该与用于JSP taglib元素的uri属性的东西相匹配。Taglib-location元素给出TLD文件的实际位置。例如，假如你将文件chart-tags- 1.3beta.tld放在WebApp/WEB-INF/tlds中。现在，假如web.xml在web- app元素内包含下列内容。<br>&lt;taglib&gt;<br>&lt;taglib-uri&gt;/charts.tld&lt;/taglib-uri&gt;<br>&lt;taglib-location&gt;<br>/WEB-INF/tlds/chart-tags-1.3beta.tld<br>&lt;/taglib-location&gt;<br>&lt;/taglib&gt;<br>给出这个说明后，JSP页面可通过下面的简化形式使用标签库。<br>&lt;%@ taglib uri="/charts.tld" prefix="somePrefix" %&gt;<br><br>14 指定应用事件监听程序<br><br>应用事件监听器程序是建立或修改servlet环境或会话对象时通知的类。它们是servlet规范的版本2.3中的新内容。这里只简单地说明用来向Web应用注册一个监听程序的web.xml的用法。<br>注册一个监听程序涉及在web.xml的web-app元素内放置一个listener元素。在listener元素内，listener-class元素列出监听程序的完整的限定类名，如下所示：<br>&lt;listener&gt;<br>&lt;listener-class&gt;package.ListenerClass&lt;/listener-class&gt;<br>&lt;/listener&gt;<br>虽然listener元素的结构很简单，但请不要忘记，必须正确地给出web-app元素内的子元素的次序。listener元素位于所有的 servlet 元素之前以及所有filter-mapping元素之后。此外，因为应用生存期监听程序是serlvet规范的2.3版本中的新内容，所以必须使用 web.xml DTD的2.3版本，而不是2.2版本。<br>例如，程序清单5-20给出一个名为ContextReporter的简单的监听程序，只要Web应用的Servlet-Context建立（如装载Web应用）或消除（如服务器关闭）时，它就在标准输出上显示一条消息。程序清单5-21给出此监听程序注册所需要的web.xml文件的一部分。<br><br>程序清单5-20 ContextReporterjava<br>package moreservlets;<br><br>import javax.servlet.*;<br>import java.util.*;<br><br>/** Simple listener that prints a report on the standard output <br>* when the ServletContext is created or destroyed.<br>* </p>
<p><br>* Taken from More Servlets and JavaServer Pages<br>* from Prentice Hall and Sun Microsystems Press,<br>* <a href="http://www.moreservlets.com/." target=_blank>http://www.moreservlets.com/.</a><br>* &#169; 2002 Marty Hall; may be freely used or adapted.<br>*/<br><br>public class ContextReporter implements ServletContextListener {<br>public void contextInitialized(ServletContextEvent event) {<br>System.out.println("Context created on " +<br>new Date() + ".");<br>}<br><br>public void contextDestroyed(ServletContextEvent event) {<br>System.out.println("Context destroyed on " +<br>new Date() + ".");<br>}<br>}<br><br><br>程序清单5-21 web.xml（声明一个监听程序的摘录）<br>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br>&lt;!DOCTYPE web-app<br>PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br>"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br><br>&lt;web-app&gt;<br>&lt;!-- ... --&gt;<br>&lt;filter-mapping&gt; &#8230; &lt;/filter-mapping&gt;<br>&lt;listener&gt;<br>&lt;listener-class&gt;package.ListenerClass&lt;/listener-class&gt;<br>&lt;/listener&gt;<br>&lt;servlet&gt; ... &lt;/servlet&gt;<br>&lt;!-- ... --&gt;<br>&lt;/web-app&gt;<br><br><br>15 J2EE元素<br><br>本节描述用作J2EE环境组成部分的Web应用的web.xml元素。这里将提供一个简明的介绍，详细内容可以参阅http: //java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf的 Java 2 Plantform Enterprise Edition版本1.3规范的第5章。<br>l distributable<br>distributable 元素指出，Web应用是以这样的方式编程的：即，支持集群的服务器可安全地在多个服务器上分布Web应用。例如，一个可分布的应用必须只使用 Serializable对象作为其HttpSession对象的属性，而且必须避免用实例变量（字段）来实现持续性。distributable元素直接出现在discription元素之后，并且不包含子元素或数据，它只是一个如下的标志。<br>&lt;distributable /&gt;<br>l resource-env-ref<br>resource -env-ref元素声明一个与某个资源有关的管理对象。此元素由一个可选的description元素、一个resource-env-ref- name元素（一个相对于java:comp/env环境的JNDI名）以及一个resource-env-type元素（指定资源类型的完全限定的类），如下所示：<br>&lt;resource-env-ref&gt;<br>&lt;resource-env-ref-name&gt;<br>jms/StockQueue<br>&lt;/resource-env-ref-name&gt;<br>&lt;resource-env-ref-type&gt;<br>javax.jms.Queue<br>&lt;/resource-env-ref-type&gt;<br>&lt;/resource-env-ref&gt;<br>l env-entry<br>env -entry元素声明Web应用的环境项。它由一个可选的description元素、一个env-entry-name元素（一个相对于java: comp/env环境JNDI名）、一个env-entry-value元素（项值）以及一个env-entry-type元素（java.lang程序包中一个类型的完全限定类名，java.lang.Boolean、java.lang.String等）组成。下面是一个例子：<br>&lt;env-entry&gt;<br>&lt;env-entry-name&gt;minAmout&lt;/env-entry-name&gt;<br>&lt;env-entry-value&gt;100.00&lt;/env-entry-value&gt;<br>&lt;env-entry-type&gt;minAmout&lt;/env-entry-type&gt;<br>&lt;/env-entry&gt;<br>l ejb-ref<br>ejb -ref元素声明对一个EJB的主目录的应用。它由一个可选的description元素、一个ejb-ref-name元素（相对于java: comp/env的EJB应用）、一个ejb-ref-type元素（bean的类型，Entity或Session）、一个home元素（bean的主目录接口的完全限定名）、一个remote元素（bean的远程接口的完全限定名）以及一个可选的ejb-link元素（当前bean链接的另一个 bean的名称）组成。<br>l ejb-local-ref<br>ejb-local-ref元素声明一个EJB的本地主目录的引用。除了用local-home代替home外，此元素具有与ejb-ref元素相同的属性并以相同的方式使用</p>
<img src ="http://www.blogjava.net/zhuyan/aggbug/106763.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyan/" target="_blank">朱岩</a> 2007-03-27 21:08 <a href="http://www.blogjava.net/zhuyan/articles/106763.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>