Servlet3.1标准学习笔记

Servlet3.1标准学习笔记

1.Servlet默认是线程不安全的,需要开发人员处理多线程问题。

通常Web容器对于并发请求将使用同一个servlet处理,并且在不同的线程中并发执行service方法。

2.doPutdoDelete方法允许Servlet开发人员让支持HTTP/1.1的客户端使用这些功能。HttpServlet中的doHead 方法可以认为是doGet方法的一个特殊形式,它仅返回由doGet 方法产生的header 信息。doOptions方法返回当前servlet支持的HTTP方法(译者注:通过Allow响应头返回支持的HTTP 操作,如GETPOST)。 doTrace方法返回的响应包含TRACE 请求的所有头信息。

3.HttpServlet 定义了用于支持有条件GET 操作的getLastModified 方法。所谓的有条件GET 操作是指客户端 通过GET请求获取资源时,当资源自第一次获取那个时间点发生更改后才再次发生数据,否则将使用客户端缓存的数据。在一些适当的场合,实现此方法可以更有效的利用网络资源,减少不必要的数据发送。

4.对于未托管在分布式环境中(默认)的servlet而言,servlet容器对于每一个Servlet声明必须且只能产生一个实例。不过,如果Servlet实现了SingleThreadModel接口,servlet容器可以选择实例化多个实例以便处理高负荷请求或者串行化请求到一个特定的实例。

如果Servlet以分布式方式进行部署,容器可以为每个虚拟机(JVM)的每个Servlet声明产生一个实例。但是,如果在分布式环境中servlet实现了SingleThreadModel接口,此时容器可以为每个容器的JVM实例化多个Servlet实例。

5.SingleThreadModel接口的作用是保证一个特定的servlet实例的service方法在一个时刻仅能被一个线程执行,一定要注意,此包装仅适用于每一个servlet实例,因此容器可以选择池化这些对象。有些对象可以在同一时刻被多个servlet实例访问,如HttpSession实例,可以在一个特定的时间对多个Servlet可用,包括哪些实现了SingleThreadModel接口的Servlet

6.Servlet容器通过调用Servlet实例的init方法完成初始化,init方法定义在Servlet接口中,并且提供一个唯一的ServletConfig接口实现的对象作为参数,该对象每个Servlet实例一个。配置对象允许Servlet访问由Web应用配置信息提供的键值对的初始化参数。该配置对象也提供给Servlet去访问一个ServletContext对象,ServletContext描述了Servlet的运行时环境。

7.客户端请求由ServletRequest类型的request对象表示。Servlet封装响应并返回给请求的客户端,该响应由ServletResponse类型的response表示。这两个对象(requestresponse)是由容器通过参数传递到Servlet接口的service方法的。

HTTP请求的场景下,容器提供的请求和响应对象具体类型分别是HttpServeltRequestHttpServletResponse。需要注意的是,由Servlet容器初始化的某个Servlet实例在服务期间,可以在生命周期中不处理任何请求。

8.ServletException表示在处理请求过程中发生了错误,容器应该采取适当措施清理请求。

UnavailableException表示servlet不能处理请求,可能是临时的也可能是永久的。如果UnavailableException表示的是一个永久性的不可用,Servlet容器必须从服务中移除这个Servlet,调用它的destory方法,并释放Servlet实例。所有被容器拒绝的请求,都会返回一个SC_NOT_FOUND(404)响应。

如果UnavailableException表示的是一个临时性的不可用,容器可以选择在临时不可用的这段时间内路由任何请求到Servlet。所以在这段时间内被容器拒绝的请求,都会返回一个SC_SERVICE_UNAVAILABLE(503)响应状态码,且同时会返回一个Retry-After头指示此Servlet什么时候可用。容器可选择忽略永久性和临时性不可用的区别,并把UnavailableExceptions视为永久性的,从而Servlet抛出UnavailableException后需要把它从服务中移除。

9.Servelet3.0引入了异步处理请求的能力,是线程可以返回到容器,从而执行更多的任务。当开始移除处理请求时,另一个线程或回调可以或者产生响应,或者调用完成(complete)或者请求分派(dispatch),这样,它可以在容器上下文使用AsyncContext.dispatch方法运行。

从一个Servlet分派时,把asyncSupported=true设置为false是允许的。这种情况下,当servletservice方法不支持异步退出时,响应将被提交,且容器负责调用AsyncContextcomplete,以便所有感兴趣的AsyncListener得到触发通知。过滤器作为清理要完成的异步任务持有的资源的一种机制,也应该使用AsyncListener.onComplete触发的结果。

从一个同步Servlet分派到另一个异步Servlet是非法的。不过与改点不同的是当应用调用startAsync时将抛出IllegalStateException。这将允许servlet只能作为同步的或异步的Servlet

10.AsyncContext该类表示在ServletRequest启动的异步操作执行上下文,AsyncContext由之前描述的ServletRequest.startAsync创建并初始化。

任何执行dispath方法期间可能抛出的错误或异常必须由容器捕获及处理:

1)调用所有由AsyncContext创建的并注册到ServletRequestAsyncListener实例的AsyncListener.onError(AsyncEvent)方法,可以通过AsyncEvent.getThrowable()获取到捕获的Throwable

2)如果没有监听器调用AsyncContext.complete或任何AsyncContext.dispatch方法,然后执行一个状态码为HttpServletResponse.SC_INTERNAL_SERVER_ERROR的出错分派,并且可以通过RequDispatcher.ERROR_EXCEPTION请求属性获取Throwable值。

3)如果没有找到匹配的错误页面,或错误页面没有调用AsyncContext.complete()或任何AsyncContext.dispatch方法,则容器必须调用AsyncContext.complete

在异步操作超时的情况下,容器必须按照如下步骤运行:

1)当异步操作启动后调用注册到ServletRequest的所有AscyncListener实例的AsyncListener.onTimeout方法

2)如果没有监听器调用AsyncContext.complete()或任何AsyncContext.dispatch方法,执行一个状态码为HttpServletResponse.SC_INTERNAL_SERVER_ERROR出错分派。

3)如果没有找到匹配的错误页面,或者错误页面没有调用AsyncContext.complete()或者任何Asyn.dispath方法,则容器必须调用AsyncContext.complete()

如果在AsyncListener中调用的方法抛出异常,将记录下来且将不影响任何其他AsyncListener的调用。

默认情况下是不支持JSP的异步处理,因为它是用于内容审查且异步处理可能在内容生成之前已经完成。这取决于如何处理这种情况。一旦完成了所有的异步活动,使用AsyncContext.dispatch分派到的JSP页面可以用来生成内容。

11.HTTP/1.1Upgrade通用头(general-header)允许客户端指定其支持和希望使用的其他通信协议。如果服务器找到合适的切换协议,那么新的协议将在之后的通信中使用。Servlet容器提供了HTTP升级机制。不过,Servlet容器本身不知道任何升级协议。协议处理封装在HttpUpgradeHandler协议处理器。在容器和HttpUpgradeHandler协议处理器之间通过字节流进行数据读取或写入。

当收到一个升级(upgrade)请求,servlet可以调用HttpServletRequest.upgrade方法启动升级处理。该方法实例化给定的HttpUpgradeHandler类,返回的HttpUpgradeHandler实例可以被进一步定制。应用准备和发送一个合适的响应到客户端。退出servlet service方法之后,servlet容器完成所有过滤器的处理并标记连接已交给HttpUpgradeHandler协议处理器处理。然后调用HttpUpgradeHandler协议处理器init方法,传入一个WebConnection以允许HttpUpgradeHandler协议处理器访问数据流。

Servlet过滤器仅处理初始的HTTP请求和响应,然后他们将不会再参与到后续的通信中。换句话说,一旦请求被升级,它们将不会被调用。

协议处理器(ProtocolHandler)可以使用非阻塞IO接收和发送消息。

当处理HTTP升级时,开发人员负责线程安全的访问ServletInputStreamServletOutputStream

当升级处理已经完成,将调用HttpUpgradeHandler.destory方法。

12.servlet的请求参数以字符串的形式作为请求的一部分从客户端发送servlet容器。当请求时一个HttpServletRequest对象,且符合下面参数可用时描述的条件时,容器从URI查询字符串和POST数据中填充参数。参数以一系列的名值对的形式保存。任何给定的参数和名称可存在多个参数值。

以下是在POST表单数据填充到参数集前必须满足的条件:

1)该请求是一个HTTP或者HTTPS请求。

2HTTP请求的方法是POST

3)内容类型是application/x-www-form-urlencoded.

4)该servlet已经对request对象的任意getPararmeter方法进行了初始调用。

13.当数据以multipart/from-data的格式发送时,servlet容器支持文件上传

1servlet处理注解“@MultipartConfig”标注的请求。

2)为了servlet处理请求,部署描述符包含了一个multipart-config元素。

如果servlet容器提供multipart/form-data格式数据的处理,可以同HttpServletRequset中的以下方法得到:

1public Collection<Part> getParts()

2public Part getPart(String name)

注:Part类代表从multipart/from-data格式的POST请求中接收到的一个部分或表单项。每个part都可通过Part.getInputStream方法访问头部,相关的内容类型和内容。

对于表单数据的Content-Disposition,即使没有文件名,也可使用part的名称通过HttpServletRequestgetParametergetParameterValues方法得到part的字符串值。

如果servlet的容器不提供multi-part/form-data格式数据的处理,这些数据将可通过HttpServletRequest.getInputStream得到。

14.属性是与请求相关联的对象。属性可以由容器设置来表达信息,否则无法通过API标示,或者由servlet设置将信息传达给另一个servlet(通过RequestDispatcher)。属性通过ServletRequest接口中下面的方法来访问:

1getAttribute

2getAttributeNames

3setAttribute

只有一个属性值可与一个属性名称相关联。以前缀java.javax.开头的属性名称是本规范的保留定义。同样地,以前缀sun.com.sun.oraclecom.oracle开头的属性名是Oracle Corporation的保留定义。

15.引导servlet服务请求的请求路径由许多重要部分组成。以下元素从请求URI路径得到,并通过request对象公开:

1Context Path:与ServletContext相关联的路径前缀是这个servlet的一部分。如果这个上下文是基于Web服务器的URL命名空间基础上的默认上下文,那么这个路径将是一个空字符串。否则,如果上下文不是基于服务器的命名空间,那么这个路径以"/" 字符开始,但不以"/" 字符结束。

2Servlet Path:路径部分直接与激活请求的映射对应。这个路径以"/"字符开头,如果请求与"/*"“”模式匹配,在这种情况下,它是一个空字符串。

3PathInfo:请求路径的一部分,不属于Context PathServlet Path。如果没有额外的路径,它要么是null,要么是以"/"开头的字符串。

重要的是要注意,除了请求URI和路径部分的URL编码差异外,下面的等式永远为真:

reuqestURI=contextPath+servletPath+pathInfo

16.API中有两个方便的方法,允许开发者获得与某个特定的路径等级的文件系统路径。这些方法是:

1ServletContext.getRealPath

2HttpServletRequest.getPathTranslated

getRealPath方法需要一个字符串参数,并返回一个字符串形式的路径,这个路径对应一个在本地文件系统上的文件。getPathTranslated方法推断出请求的pathInfo的实际路径。

这些方法在servlet容器无法确定一个有效的文件路径的情况下,如Web应用程序从归档中,在不能访问本地的远程文件系统上,活在一个数据库中执行时,这些方法必须返回nullJAR文件中META-INF/resources目录下的资源,只有当调用getRealPath()方法时才认为容器已经从包含它的JAR文件中解压,在这种情况下,必须返回解压缩后的位置。

17.servlet容器的非阻塞IO允许开发人员在数据可用时读取数据或在数据可写时写数据。非阻塞IO仅对在ServletFilter中的异步请求处理和升级处理有效。否则,当调用ServletInputStream.setReadListenerServletInputStream.setWriteListener方法时将抛出IllegalStateException

一旦把监听器与给定的ServletInputStream关联起来,当数据可以读取,所有的数据都读取完或如果处理请求时发生错误,容器调用ReadListener的方法。注册一个ReadListener将启动非阻塞IO。在那时切换到传统的阻塞IO是非法的,且必须抛出IllegalStateException。在当前请求范围内,随后调用setReadListener是非法的且必须抛出IllegalStateException

18.HttpServletRequest接口提供了getCookies方法来获得请求中的cookie的一个数组。这些cookie是从客户端发送到服务器端的客户端发出的每个请求上的数据。

如果请求已经通过一个安全协议发送过,如HTTPS,必须通过ServletRequest接口的isSecure方法公开该信息。Web容器必须公开下列属性给servlet程序员:

密码套件               javax.servlet.request.cipher_suite                 String

算法的位大小        javax.servlet.request.key_size                        Integer

SSL会话id             javax.servlet.request.ssl_session_id               String

如果有一个与请求相关的SSL证书,它必须由servlet容器以java.security.cert.X509Certificate类型的对象数组暴露给servlet程序员并可通过一个javax.servlet.request.X509Certificate类型的ServletRequest属性访问。

19.客户端可以选择希望Web服务器用什么语言来响应。该信息可以和使用Accept-Language头与HTTP/1.1规范中描述的其他机制的客户端通信。

1getLocale    返回客户端请求要接受内容的首选语言环境。

2getLocales   返回一个Locale对象的枚举,从首选语言环境开始顺序递减,这些语言环境是可被客户接受的语言环境。

如果客户端没有指定首选语言环境,getLocale方法返回的语言环境必须是servlet容器默认的语言环境,而getLocales方法必须返回只包含一个默认语言环境的Local元素的枚举。

20.许多浏览器不随着Content-Type头一起发送字符编码限定符,而是根据读取HTTP请求确定字符编码。如果客户端请求没有指定请求默认的字符编码,容器用来创建请求读取器和解析POST数据的编码必须是“ISO-8859-1”。然而,为了向开发人员说明客户端没有请求默认的字符编码,在这种情况下,客户端发送字符编码失败,容器从getCharacterEncoding 方法返回null.

如果客户端没有设置字符编码,并使用不同的编码来编码请求数据,而不是使用上面描述的默认的字符编码,那么可能会发生数据损坏。Servlet接口添加了一个新的方法,setCharacterEncoding(String enc)。开发人员可以通过调用该方法来覆盖由容器提供的字符编码。必须在解析任何post数据或从请求读取任何输入之前调用此方法。此方法一旦调用,将不会影响已经读取的数据的编码。

21.每个request对象只在servletservice方法的作用域内,或过滤器的doFilter方法的作用域内有效,除非该组件启用了异步处理并且调用了request对象的startAsync方法。在发生异步处理的情况下,request对象一直有效,知道调用AsyncContextcomplete方法。容器通常会重复利用request对象,以避免创建request对象的性能开销。开发人员必须注意的是,不建议在上述范围之外保持startAsync方法还没有被调用的请求对象的引用,因为这样可能产生不确定的结果。

在请求升级的情况下,如上描述依然成立。

22.ServletContextServlet上下文)接口定义了servlet运行在的Web应用的视图。容器供应商负责提供Servlet容器的ServletContext接口的实现。Servlet可以使用ServletContext对象记录事件,获取URL引用的资源,存钱当前上下文的其他Servlet可以访问的属性。

ServletContextWeb服务器中已知路径的根。例如,Servlet上下文可以从http://www.mycorp.com/catalog找出,/catalog请求路径称为上下文路径,所有以它开头的请求都会被路由到与ServletContext相关联的Web应用。

部署在容器中的每一个Web应用都有一个ServletContext接口的实例与之关联。在容器分布在多态虚拟机的情况下,每个Web应用在每个JVM中都将有一个ServletContext实例。

如下ServletContext接口方法允许Servlet访问由应用开发人员在Web应用中的部署描述符中指定的上下文初始化参数:

1getInitParameter

2getInitParameterNames

应用开发人员使用初始化参数来表达配置信息。

如下的方法只能在应用实例化的过程中通过一个ServletContextListener实现的contextInitialized方法或者一个ServletContainerInitializer实现的onStartup方法调用。除了添加ServletFilter,也可以查找关联到ServletFilter的一个Registraction对象实例,或者到Servlet或者Filter的所有Registration对象的map

ServletContext添加指定class名称的监听器。ServletContext将使用由与应用关联的classloader装载加载该给定名称的class,且它们必须实现一个或多个以下接口:

1javax.servlet.ServletContextAttributeListener

2javax.servlet.ServletRequestListener

3javax.servlet.ServletRequestAttributeListener

4javax.servlet.http.HttpSessionListener

5javax.servlet.http.HttpSessionAttributeListener

6javax.servlet.http.HttpSessionIdListener

如果ServletContext传到了ServletContainerInitializeronStartup方法,则给定名字的类可以实现除上面列出的接口之外的javax.servlet.ServletContextListener。作为该方法调用的一部分,容器必须装载指定类名的class,以确保其实现了所需的接口之一。如果给定名字的类实现了一个监听器接口,则其调用顺序和声明顺序是一样的。换句话说,如果它实现了javax.servlet.ServletRequestListenerjavax.servlet.http.HttpSessionListener,那么新的监听器将被添加到该接口的有序监听器列表的末尾。

23.上下文属性

Servlet可以使用指定的名字将对象属性绑定到上下文。同一个Web应用内的其他任何Servlet可以使绑定到上下文的任意属性。

JVM中创建的上下文属性是本地的,这可以防止从一个分布式容器的共享内存存储中获取ServletContext属性,当需要在运行在分布式环境的Servlet之间共享信息时,该信息应该被放到session或存储到数据库,或者设置到企业级JavaBean组件。

24.资源

ServletContext接口提供了直接访问Web应用中静态内容层次机构的文件的方法,包括HTMLGIFJPEG文件

1getResource

2getResourceAsStream

getResourcegetResourceAsStream方法需要一个以“/”开头的String字符串作为参数,给定的资源路径是相对于上下文的根,或者相对于web应用的WEB-INF/lib目录下的JAR文件中的META-INF/resources目录。这两个方法首先根据请求的资源查找web应用上下文的根,然后查找所有WEB-INF/lib目录下的JAR文件。查找WEB-INF/lib目录中JAR文件的顺序是不确定的。这种层次结构的文件可以存在于服务器的文件系统,Web应用的归档文件,远程服务器,或者其他位置。

这两个方法不能获取动态内容。

25.Servlet上下文不会在虚拟主机之间共享。ServletContext接口的getVirtualServerName方法允许访问ServletContext部署在的逻辑主机的配置名字。该方法必须对所有部署在逻辑主机上的所有servlet context返回同一个名字。且该方法返回的名字必须是明确的、每个逻辑主机稳定的、和适合用于关联服务器配置信息和逻辑主机。

26.每一个servlet上下文都需要一个临时的存储目录。Servlet容器必须为每一个servlet上下文提供一个私有的临时目录,并将通过javax.servlet.context.tempdir上下文属性使其可用,关联该属性的对象必须是java.io.File类型。该要求公认为在多个servlet引擎实现中提供一个通用的便利。当servlet容器重启时,它不需要去保持临时目录中的内容,但必须确保一个servelt上下文的临时目录中的内容对运行在同一个servlet容器的其他Web应用的上下文不可见。

27.响应对象封装所有从服务器返回给客户端的信息,在HTTP协议中,从服务器返回客户端的信息是通过HTTP头信息或请求的信息体传输的。

ServletResponse接口的如下方法运行servlet访问和设置缓冲信息:

1getBufferSize 返回使用的底层缓冲区大小。如果没有使用缓冲,该方法必须返回一个int0.

2setBufferSize  Servlet可以请求setBufferSize方法设置一个最佳的缓冲大小。

3isCommitted 返回一个表示是否有任何响应字节已经返回到客户端的boolean值。 

4reset 当响应没有提交时,该方法情况缓冲区的数据。头信息,状态码和在调用reset之前servlet调用getWritergetOutputStream设置的状态也必须被清空。

5resetBuffer 如果响应没有被提交,该方法将清空缓存区的内容,但不清空请求头和状态码。

6flushBuffer 强制刷出缓冲区的内容到客户端

Servlet可以使用如下HttpServletResponse接口中的方法设置HTTP响应头:

1setHeader 设置一个给定名字和值的header。之前的header将被新的header替换。

2addHeader方法使用给定的名字添加一个header值到set

28.非阻塞IO

非阻塞IO仅对在ServletFilter中的异步请求处理和升级处理有效。否则,当调用ServletInputStream.setReadListenerServletOutputStream.setWriteListener方法时将抛出IllegalStateException

29.HttpServletResponse提供了如下简便方法:

1sendRedirect 将设置适当的header和内容体将客户端重定向到另一个地址。使用相对URL路径调用该方法是合法的,但是底层的容器必须将传回到客户端的相对地址转换为全路径URL

2sendError 方法将设置适当的header和内容体用于返回给客户端返回错误消息。可以为sendError方法提供一个可选的String参数用于指定错误的内容体。

30.Servlet应设置responselocale和字符集。使用ServletResponse.setLocal方法设置local。该方法可以重复调用;但相应被提交后调用该方法不会产生任何作用。如果在页面被提交之前Servlet没有设置locale,容器的默认locale将用来确定相应的locale,但是没有指定与客户端通信的规范,例如使用HTTP情况下的Context-Language header

setCharacterEncodingsetContentTypesetLocale方法可以被重复的调用来改变字符编码。

ServletResponse接口的getWriter方法被调用或响应被提交之前,如果servlet没有指定字符编码,默认使用ISO-8859-1

当响应被关闭时,容器必须立即刷出响应缓冲区中的所有剩余的内容到客户端。

以下事件表明servlet满足了请求且响应对象即将关闭:

1servletservice方法终止。

2)响应的setContentLengthsetContentLengthLong方法制定了大于零的内容量,且已经写入到响应。

3sendError方法已调用

4sendRedirect方法已调用。

5AsyncContextcomplete方法已调用。

每个响应对象是只有当在servletservice方法的范围内或在filterdoFilter方法范围内是有效的,除非该组件关联的请求对象已经开启异步处理。如果相关的请求已经启动异步处理,那么知道AsyncContextcomplete方法被调用,请求对象一直有效。为了避免响应对象创建的性能开发,容器通常回收响应对象。在相关的请求的startAsync还没有调用时,开发人员必须意识到保持到响应对象引用,超出之上描述的范围可能导致不确定的行为。

31.过滤器是一种代码重用的技术,它可以改变HTTP请求的内容,响应,及header信息。过滤器通常不产生响应或像servlet那样对请求作出响应,而是修改或调整到资源的请求,修改或调整来自资源的响应。

供开发人员使用的过滤器功能有如下几种类型:

1)在执行请求之前访问资源

2)在执行请求之前处理资源的请求

3)用请求对象的自定义版本包装请求,对请求的header和数据进行修改

4)用响应对象的自定义版本包装响应,对响应的header和数据进行修改。

5)拦截资源调用之后的调用

6)按指定顺序执行的零个、一个或多个拦截器作用于Servlet,一组Servlet或静态内容

应用开发人员通过实现javax.servlet.Filter接口并提供一个公共的空参构造器来创建过滤器。该类及构建Web应用的静态资源和Servlet打包在Web应用归档文件中。Filter在部署描述符中通过<filter>元素声明。一个过滤器或一组过滤器可以通过在部署描述符中定义<filter-mapping>来为调用配置。可以使用servlet的逻辑视图名把过滤器映射到一个特定的servlet,或者使用URL模式把一组Servlet和静态资源内容映射到过滤器。

在部署描述符中声明的每个<filter>在每个JVM的容器中仅实例化一个实例。容器提供了声明在过滤器的部署描述符的过滤器configFilterConfig),对Web应用的ServletContext的引用,和一组初始化参数。

过滤器的核心概念是包装请求或响应,以便它可以覆盖行为执行过滤任务。在这个模型中,开发人员不仅可以覆盖请求和响应对象上已有的方法,也能提供新的API以适用于对过滤器链中剩下的过滤器或目标web资源做特殊的过滤任务。

32.可以使用部署描述符中的<init-params>元素把一组初始化参数关联到过滤器。这些参数的名字和值在过滤器运行期间可以使用过滤器的FilterConfig对象的getInitParametergetInitParameterNames方法得到。另外,FilterConfig提供访问Web应用的ServletContext用于加载资源,记录日志,在ServletContext的属性列表存储状态。链中最后的过滤器和目标servlet或资源必须执行在同一个调用线程。

过滤器可以通过@WebFilter注解定义或者在部署描述符中使用<filter>元素定义。在这个元素中,可声明如下内容:

1filter-name:用于映射过滤器到servletURL

2filter-class:由容器用于标示过滤器类型

3init-params:过滤器的初始化参数

容器必须为部署描述符中定义的每个过滤器声明实例化一个Java类实例。因此,如果开发人员对一个过滤器类声明了两次,则容器将实例化两个相同的过滤器类的实例。

一旦在部署描述符中声明了过滤器,配置人员使用<filter-mapping>定义Web应用中的servlet和静态资源到过滤器的应用。过滤器可以使用<servlet-name>元素关联到一个Servlet。过滤器可以使用<url-pattern>风格的过滤器映射关联到一组servlet和静态内容。

当使用<url-pattern>风格配置<filter-mapping>元素,容器必须使用路径映射规则(path mapping rule)决定<url-pattern>是否匹配请求URI

容器使用的用于构建应用到一个特定请求URI的过滤器链的顺序如下所示:

1)首先,<url-pattern>按照在部署描述符中的出现顺序匹配过滤器映射。

2)接下来,<servlet-name>按照在部署描述符中的出现顺序匹配过滤器映射。

如果过滤器映射同时包含了<servlet-name><url-pattern>,容器必须展开过滤器映射为多个过滤器映射(每一个<servlet-name><url-pattern>一个),保持<servlet-name><url-pattern>元素顺序。

33.通过在部署描述符中使用心得<dispatcher>元素,开发人员可以为filter-mapping指定是否想要过滤器应用到请求,当:

1)请求直接来自客户端

可以由一个带有REQUEST值的<dispatcher>元素,或者没有任何<dispatcher>元素来表示。

2)使用表示匹配<url-pattern><servlet-name>web组件的请求分配器的forward()调用情况下处理请求。

可以由一个带有FORWARD值的<dispatcher>元素表示。

3)使用表示匹配<url-pattern><servlet-name>Web组件的请求分派器的include()调用情况下处理请求。

可以由一个带有INCLUDE值的<dispatcher>元素表示。

4)使用第106错误处理指定的错误页面机制处理匹配<url-pattern>的错误资源的请求。

可以由一个带有ERROR值的<dispatcher>元素表示。

5)使用第10页指定的异步处理中的异步上下文分派机制对web组件使用dispatche调用处理请求。

可以由一个带有ASYNC值的<dispatcher>元素表示。

6)或之上1,2,3,4,5的任何组合。

34.HTTP被设计为一种无状态协议。为了构建有效的Web应用,必须与来自一个特定的客户端的请求彼此相关关联。

1Cookies

通过HTTP cookie的会话跟踪是最常用的会话跟踪机制,且所有servlet容器都应该支持。

容器向客户端发送一个cookie,客户端后续到服务器的请求都将返回该cookie,明确地将请求与会话关联。会话跟踪cookie的标准名字必须是JSESSIONID,所有3.0兼容的容器必须支持。容器也允许通过容器指定的配置自定义会话跟踪cookie的名字。

2SSL会话

安全套接字层,在HTTPS使用的加密技术,有一种内置机制允许多个来自客户端的请求被明确识别为同一会话。Servlet容器可以很容易地使用该数据来定义会话。

3URL重写

URL重写是会话跟踪的最低标准。当客户端不接受cookie时,服务器可使用URL重写作为会话跟踪的基础。URL重写设计添加数据、会话ID、容器解析URL路径从而请求与会话相关联、

会话ID必须被编码为URL字符串中的一个路径参数。参数的名称必须是jessionid.

URL重写在日志、书签、refer header、缓存的HTMLURL工具条中暴露会话标识。在支持cookieSSL会话的情况下,不应该使用URL重写作为会话跟踪机制。

与每个会话相关联的是一个包含唯一标识符的字符串,也被称为会话ID,会话ID的值能通过调用javax.servlet.http.HttpSession.getId()获取,且能在创建后通过调用javax.servlet.http.HttpServletRequest.changeSessionId()改变。

HttpSession对象必须被限定在应用(或servlet上下文)级别。底层的机制,如使用cookie建立会话,不同的上下文可以是相同,但所引用的对象,包括该对象中的属性,决不能在容器上下文之间共享。

35.servlet可以按名称绑定对象属性到HttpSession实现,任何绑定到会话的对象可用于任意其他的Servlet,其属于同一个ServletContext且处理属于相同会话中的请求。

一些对象可能需要在它们被放进会话或从会话中移除时得到通知。这些信息可以从HttpSessionBingingListener接口实现的对象中获取。这个接口定义了以下方法,用于标识一个对象被绑定到会话或从会话解除绑定时。

1valueBound

2valueUnbound

Servlet容器定义了默认的会话超时时间,且可以通过HttpSession接口的getMaxInactiveInterval方法获取,也可以通过setMaxInactiveInterval方法设置超时时间。

HttpSession接口的getLastAccessedTime方法允许servlet确定在当前请求之前的会话的最后访问时间。

写分布式应用的开发人员应该意识到容器可能运行在多个Java虚拟机中,开发人员不能依赖静态变量存储应用状态。应该用企业Bean或数据库存储这种状态。

36.web应用中,使用注解的类仅当它们位于WEB-INF/classes目录中,或它们被打包到位于应用的WEB-INF/lib中的jar文件中时它们的注解才将被处理。

Web应用部署描述符的web-app元素包含一个新的"metadata-complete"属性。"metadata-complete"属性定义了web描述符是否是完整的,或是否应该在部署时检查jar包中的类文件和web fragments。如果“metadata-complete”设置为"true",部署工具必须忽略存在于应用类文件中的所有指定部署信息的servlet注解和web fragments。如果metadata-complete属性没有指定或设置为false,部署工具必须检查应用的类文件的主键,并扫描web fragments

@WebServlet该注解用于在Web应用中定义Servlet组件。该注解在一个类上指定幷包含声明Servlet的元数据。必须指定注解的urlPatternsvalue属性。所有其他属性是可选的默认设置。当注解上唯一属性是url Patterns时推荐使用value且当也有使用其他属性时使用urlPatterns属性。在同一注解上同时使用valueurlPatterns属性是非法的。如果没有指定Servlet名字则默认是全限定类名。被注解的Servlet必须指定至少一个url模式进行部署。如果同一个Servlet类以不同的名字声明在部署描述符中,必须实例化一个新的Servlet实例。如果使用不同名字添加的同一个Servlet类使用编程式添加和配置Servlet”的编程式API添加到ServletContext,使用@WebServlet注解声明的属性值必须被忽略,必须创建一个指定名字的Servlet的新的实例。

@WebServlet注解的类必须继承javax.servlet.http.HttpServlet类。

37.@WebFilter用于在Web应用中定义Filter。该注解在一个类上指定且包含声明过滤器的元数据。如果没有指定Filter名字则默认是全限定类名。注解的urlPatterns属性,servletNames属性或value属性必须被指定。当注解上唯一属性是url模式时推荐使用value且当有使用其他属性时使用urlPatterns属性。在同一注解上同事使用valueurlPatterns属性是非法的。

@WebFilter注解的类必须实现javax.servlet.Filter

@WebInitParam用于指定必须传递到ServletFilter的任何初始化参数。它是WebServletWebFilter注解的一个属性。

@WebListener用来获得特定web应用上下文中的各种操作时间的监听器。

@MultipartConfig该注解当指定在Servlet上时,表示请求原文是mime/multipart类型。相应servletHttpServletRequest对象必须使用getPartsgetPart方法遍历各个mime附件以获取mime附件。javax.servlet.annotation.MultipartConfiglocation属性和<multipart-config><location>元素被解析为一个绝对路径且默认为javax.servlet.context.tempdir。如果指定了相对地址,它将是相对于tempdit位置。绝对路径与相对路径的测试必须使用java.io.File.isAbsolute

当使用注解时,从WEB-INF/classesWEB-INF/lib中的不同框架jar/类加载监听器、Servlet的顺序是没有指定的。如果顺序是很重要的,那么请看web.xml模块部分和后面的web.xmlweb-fragment.xml顺序部分。顺序仅能在部署描述符中指定。

38.web模块部署描述符片段(web fragment)是web.xml的部分或全部,可以在一个类库或框架jar包的META-INF目录指定和包括。在WEB-INF/lib目录中的普通的老的jar文件即使没有web-fragment.xml也可能被认为是一个fragment

由于规范允许应用配置由多个配置文件组成(web.xmlweb-fragment.xml)的资源,从应用中多个不同的位置发现和加载,顺序问题必须被解决。

web-fragment.xml可以有一个javaee:java-identifierType类型的顶级<name>元素,且在一个web-fragment.xml中仅能有一个<name>元素。如果存在一个<name>元素,它必须考虑用于artifact顺序(除非出现重复名异常)

39.ServletContainerInitializer和编程时注册特性可以在ServletJSP容器之间提供一个清晰的职责分离,通过由Servlet容器只负责解析web.xmlweb-fragment.xml资源,而解析标签类库描述符(TLD)资源委托给JSP容器。

在此之前,web容器必须扫描TLD资源寻找任何Listener声明。使用Servlet3.0和后续版本后,该职责可以委托给JSP容器。JSP容器是内嵌到一个Servlet3.0兼容的Servlet容器中,可以提供它自己的ServletContainerInitializer实现,搜索传递到它的onStartup方法的ServletContext参数寻找任何TLD资源,扫描这些资源寻找Listener声明,并向ServletContext注册相关的Listener

40.构建Web应用时,把请求转发给另一个servlet处理、或在response中包含另一个servlet的输出通常是很有用的。RequestDispatch接口提供了一种机制来实现这种功能。当请求启用异步处理时,AsyncContext允许用户将这个请求转发到servlet容器。

实现了RequestDispatcher接口的对象,可以从ServletContext中的下面方法得到:

1getRequestDispatcher 需要一个String类型的参数描述在ServletContext作用域内的路径。这个路径必须是相对于ServletContext的根路径,或以'/'开头,或者为空。该方法根据这个路径使用servlet路径规则来查找servlet,或者把它包装成RequestDispatcher对象并返回。如果基于给定的路径没有找到相应的servlet,那么返回这个路径内容提供的RequestDispatcher

2getNamedDispatcher方法使用一个ServletContext知道的servlet名称作为参数。如果找到一个servlet,则把它包装成RequestDispatcher对象,并返回该对象。如果没有与给定名字相关的servlet,则该方法必须返回null

ServletContextServletRequest中创建RequestDispatcher对象的方法使用的路径信息中允许附加可选的查询字符串信息。

要使用请求调度器,servlet可调用RequestDispatcher接口的includeforward方法。这些方法的参数既可以是javax.servlet.Servlet接口的service方法传来的requestresponse对象实例,也可以是requestresponse包装器的子类对象实例。对于后者,包装器实例必须包装容器传递到service方法中的requestresponse对象。

41.RequestDispatcher接口的include方法可能随时被调用。Include方法的目标servlet能够访问request对象的各个方法,但是调用response对象的方法会受到更多限制。它只能把信息写到response对象的ServletOutputStreamWriter中,或提交在最后写保留在response缓冲区中的内容,或通过显式地调用ServletResponse接口的flushBuffer方法。它不能设置响应头部信息或调用任何影响响应头部信息的方法,HttpServletRequest.getSession()HttpServletRequest.getSession(boolean)方法除外。

如果默认的servletRequestDispatch.include()的目标servlet,而请求的资源不存在,那么默认的servlet必须抛出FileNotFoundException异常。如果这个异常没有被捕获和处理,以及响应还未提交,则响应状态码必须被设置为500

42.RequestDispatcher接口的forward方法,只有在没有输出提交到客户端时,通过正在被调用的servlet调用。如果response缓冲区中存在尚未提交的输出数据,这些数据内容必须在目标servletservice方法调用前清除。如果response已经提交,必须抛出一个IllegalStateException异常。

request对象暴露给目标servlet的路径元素(path elements)必须反映获得RequestDispatcher使用的路径。

唯一例外的是,如果RequestDispatcher是通过getNamedDispatcher方法获得。这种情况下,request对象的路径元素必须反映这些原始请求。

RequestDispatcher接口的forward方法无异常返回前,响应的内容必须被发送和提交,且由Servlet容器关闭,除非请求处于异步模式。如果RequestDispatcher.forward()的目标发生错误,异常信息或传回所有调用它经过的过滤器和servlet,且最终传回给容器。

43.如果请求分发的目标servlet抛出运行时异常或受检查异常ServletExceptionIOException,异常应该传播到调用的servlet。所有其它的异常都应该包装成ServletException,异常的根本原因设置成原来的异常,因为它不应该被传播。

44.实现了AsyncContext接口的对象可从ServletRequest的一个startAsync方法中获得,一旦有了AsyncContext对象,你就能够使用它的complete()方法来完成请求处理,或使用下面描述的转发方法。

45.可以使用AsyncCont中下面的方法来转发请求:

1dispatch(path) 该方法的String参数描述一个在ServletContext作用域中的路径。这个路径必须是相对于ServletContext的根路径并以'/'开头。

2dispatch(servletContext,path)  该方法的String参数描述一个在ServletContext作用域中的路径。这个路径必须是相对于ServletContext的根路径并以'/'开头。

3dispatch() 这个方法没有参数,它使用原来的URI路径。如果AsyncContext已经通过startAsync(ServletRequest,ServletResponse)初始化,且传递过来的requestHttpServletRequest的实例,那么这个请求分发到HttpServletRequest.getRequestURI()返回的URI

AsyncContext接口中的dispatch方法可被等待异步事件发生的应用程序调用。如果AsyncContext已经调用了complete方法,必须抛出IllegalStateException异常。所有不同的dispatch方法会立即返回并且不会提交response

request对象暴露给目标servlet的路径元素必须反映AsyncContext.dispatch中指定的路径。

46.一个Web应用程序以结构化的目录层次结构存在。层次结构的根目录作为文件的归档目录,这些文件是应用的一部分。由于应用的上下文路径确定了Web应用内容的URL命名空间,Web容器必须拒绝Web应用定义的上下文路径,因为可能这个URL命名空间中导致潜在的冲突。

应用程序层次结构中存在一个名为“WEB-INF”的特殊目录。这个目录包含了与应用程序相关的所有东西,这些东西不在应用程序的归档目录中。大多数WEB-INF节点都不是应用程序公共文档树的一部分。除了静态资源和WEB-INF/lib目录下打包在JAR文件中META-INF/resources目录下的JSP文件之外,WEB-INF目录下包含的其他任何文件都不能由容器直接提供给客户端访问,然而,WEB-INF目录中的内容可以通过servlet代码调用ServletContextgetResourcegetResourceAsStream方法来访问,并可使用RequestDispatcher调用公开这些内容。

WEB-INF目录中的内容有:

1/WEB-INF/web.xml部署描述文件。

2servlet和实用工具类目录/WEB-INF/classes/。此目录中类对应用程序类加载器必须是可见的。

3java归档文件区域/WEB-INF/lib/*.jar。这些文件中包括了sevletbeans,静态资源和打包在JAR文件中的JSP文件,以及其他对Web应用程序有用的使用工具类。Web应用程序的加载器必须能够从这些归档文件中加载类。

Web应用程序类加载器必须先从WEB-INF/classes目录下加载类,然后从WEB-INF/lib目录下的JAR库中加载。此外,除了静态资源打包在JAR文件中的情况外,任何来自客户端的请求访问WEB-INF/目录中的资源必须返回一个SC_NOT-FOUND(404)的响应。

可以使用标准的Java归档工具把Web应用程序打包并签名到一个Web存档格式(WAR)文件中。

当打包成这种形式时,将生成一个META-INF目录,其中包含了对java归档工具有用的信息。尽管这个目录的内容可以通过servlet代码调用ServletContextgetResourcegetResourceAsStream方法来访问,容器也不能把这个目录当做内容来响应客户端请求。此外,任何请求访问META-INF目录中的资源必须返回一个SC_NOT_FOUND(404)的响应。

47.容器用于加载WAR文件中servlet的类加载器必须允许开发人员使用getResource加载遵循正常JavaSE语义的WAR文件的JAR包中包含的任何资源。和Java EE许可协议中描述的一样,不属于Java EE产品的servlet容器不应该允许应用程序覆盖Java SE平台中的类。

一个类加载器的实现必须保证对部署到容器的每个web应用,调用Thread.currentThread.getContextClassLoader()返回一个实现了本节规定的约定的ClassLoader实例。此外,部署的每个Web应用程序的ClassLoader实例必须是一个单独的实例。容器必须在任何回调(包括监听器回调)到Web应用程序之前设置上面描述的线程上下文ClassLoader,一旦回调返回,需要把它设置成原来的ClassLoader

48.在发生错误时,Web应用程序必须能够详细说明,应用程序中的其他资源被用来提供错误响应的内容主题。

49.如果Web容器接收到一个有效的局部请求,Web容器必须检查部署描述文件中定义的欢迎文件列表。欢迎文件列表是一个没有尾随或前导的局部URL有序列表。Web服务器必须把部署描述文件中按指定顺序的每个欢迎文件添加到局部请求,并检查WAR文件中的静态资源是否映射到请求URIWeb服务器必须再把部署描述文件中指定顺序的每个欢迎文件添加到局部请求,并检查servlet是否映射到请求URIWeb容器必须将请求到WAR文件中第一个匹配的资源。容器可使用转发、重定向、或容器指定的机制将请求发送到欢迎资源,这与直接请求没有什么区别。

50.当一个Web应用程序部署到容器中,在Web应用程序开始处理客户端请求之前,必须按照下述步骤顺序执行:

1)实例化部署描述文件中<listener>元素表示的每个事件监听器的一个实例。

2)对于已实例化的实现了ServletContextListener接口的监听器实例,调用contextInitialized()方法。

3)实例化部署描述文件中<filter>元素标识的每个过滤器的一个实例,并调用每个过滤器实例的init()方法。

4)包含<load-on-starup>元素的<servlet>元素,根据load-on-startup元素值定义的顺序为每个servlet实例化一个实例,并调用每个servlet实例的init()方法。

51.如果Web应用不包含任何servlet、过滤器或监听器组件或使用注解声明相同的,那么可以不需要web.xml文件。换句话说,只包含静态文件或JSP页面的应用程序不需要一个web.xml的存在。

52.Servlet事件监听器支持在ServletContextHttpSessionServletRequest状态改变时进行事件通知。Servlet上下文监听器是用来管理应用的资源或JVM级别持有的状态。HTTP会话监听器是用来管理从相同客户端或用户进入web应用的一系列请求管理的状态或资源。Servlet请求监听器是用来管理整个Servlet请求周期的状态。一步监听器用来管理异步事件。如超时和完成异步处理。

可以有多个监听器类监听每一个事件类型,且开发人员可以为每一个事件类型指定容器调用监听器bean的顺序。

监听器类在Web应用部署描述符中使用listener元素声明。它们根据类名列出的顺序就是它们被调用的顺序。与其他监听器不同,AsyncListener类型和监听器可能仅通过编程式注册(使用一个ServletRequest)。

Web容器创建每一个监听器类的一个实例,并在应用处理第一个请求之前为事件通知注册它。

在分布式Web容器中,HttpSession实例被限定到特定的JVM服务会话请求,且ServletContext对象被限定到Web容器所在的JVM。分布式容器不需要传播Servlet上下文事件或HttpSession事件到其他JVM。监听器类实例被限定到每个JVM的每个部署描述符声明一个。

53.在收到客户端请求时,web容器确定转发到哪一个Web应用。选择的Web应用必须具有最长的上下文路径匹配请求URL的开始。当映射到Servlet时,URL匹配的一部分是上下文。

用于映射到Servlet的路径是请求对象的请求URL减去上下文和路径参数部分。下面的URL路径映射规则按顺序使用。使用第一个匹配成功的且不会进一步尝试匹配:

1)容器将尝试找到一个请求路径到servlet路径的精确匹配。成功匹配则选择该servlet

2)容器将递归地尝试匹配最长路径前缀。这是通过一次一个目录的遍历路径树完成的,使用'/'字符作为路径分隔符。最长匹配确定选择的servlet

3)如果URL最后一部分包含一个扩展名(如.jsp),servlet容器将视图匹配为扩展名处理请求的Servlet。扩展名定义在最后一部分的最后一个'.'字符之后。

4)如果前三个规则都没有产生一个servlet匹配,容器将视图为请求资源提供相关的内容。如果定义中定义了一个‘default’Servlet,它将被使用。

容器必须使用区分大小写字符串的比较匹配。

web应用部署描述符中,以下语法用于定义映射:

1)以'/'字符开始,以'/*'后缀结尾的字符串用于路径匹配。

2'*.'开始的字符串用于扩展名映射。

3)空字符串""是一个特殊的URL模式,其精确映射到应用的上下文根,即http://host:port/<context-root>/请求形式。在这种情况下,路径信息是'/'servlet路径和上下文路径是空字符串("");

4)只包含'/'字符的字符串表示应用的"default"servlet。在这种情况下,servlet路径请求时请求URL减去上下文路径,且路径信息时null.

5)所有其他字符串仅用于精确匹配。

如果容器有一个内部的JSP容器,*.jsp扩展名映射到它,允许执行JSP页面的要求。该映射被称为隐式映射。如果Web应用定义了一个*.jsp映射,它的优先级高于隐式映射。

54.声明式安全是指以在应用外部的形式表达应用的安全模型需求,包括角色、访问控制和认证需求。部署描述符是web应用中的声明式安全的主要手段。

编程式安全包括以下HttpServletRequest接口的方法:

1authenticate 允许应用由容器发起在一个不受约束的请求上下文内的来访者请求认证。

2login 允许应用执行用户名和密码收集(作为一种Form-Based Login的替代)。

3logout 提供用于应用重置来访者的请求身份。

4getRemoteUser 又涌起返回与该请求相关的远程用户(即来访者)的名字。

5isUserInRole 确定是否与该请求相关的远程用户(即来访者)在一个特定的安全角色中。

6getUserPrincipal 确定远程用户(即来访者)的Principal名称并返回一个与远程用户相关的java.security.Principal对象。调用getUserPrincipal返回的PrincipalgetName方法返回远程用户的名字。这些API允许Servlet基于获取的信息做一些业务逻辑决策。

55.@ServletSecurity提供了用于定义访问控制约束的另一种机制,相当于那些通过在便携式部署描述符中声明式或通过ServletRegistration接口的serServletSecurity方法编程式表示。Servlet容器必须支持在实现javax.servlet.Servlet接口的类(和它的子类)上使用@ServletSecurity注解。

@HttpConstraint注解用在@ServletSecurity中标示应用到所有HTTP协议方法的安全约束,且HTTP协议方法对应的@HttpMethodConstraint没有出现在@ServletSecurity注解中。

@HttpMethodConstraint注解用在@ServletSecurity注解中表示在特定HTTP协议消息上的安全约束。

定义在便携式部署描述符中的security-constraint元素用于对所有出现在该约束中的url-pattern授权。

当在便携式部署描述符中的一个security-constraint包含一个url-pattern,其精确匹配一个使用@ServletSecurity注解的模式映射到的类,该注解必须在由容器在该模式上强制实施的约束上没有效果。

@ServletSecurity注解用于定义一个方法无关的@HttpConstraint,且紧跟着一个包含零个或多个@HttpMethodConstaint规格的列表。方法无关的约束应用到那些没有定义HTTP特定方法约束的所有HTTP方法。

当没有包含@HttpMethodConstraint元素,@ServletSecurity注解相当于包含一个web-resource-collection的单个security-constraint元素,且web-resource-collection不包含http-method元素,因此涉及到所有HTTP方法。

ServletContextListener内的setServletSecurity方法用于定义应用到ServletRegistration定义的映射的安全约束。

Collection<String> setServletSecurity(ServletSecurityElement arg);

serServletSecurity方法返回一组URL pattern(可能空),其已是便携式部署描述符中的security-constraint元素的精确目标(因此,调用是不影响的)。

如果ServletContext中得到的ServletRegistration已经被初始化了,该方法抛出IllegalStateException

当便携式部署描述符中的security-constraint包含一个url-pattern其精确匹配ServletRegistration映射的pattern,调用ServletRegistrationsetServletSecurity必须对Servlet容器对pattern实施的约束没有任何影响。

56.安全角色是由应用开发人员或装配人员定义的逻辑用户分组。当部署了应用,由部署人员映射觉得到运行时环境的principal或组。

Servlet容器根据principal的安全属性为与进入请求相关的principal实施声明式或编程式安全。

这可能以如下任一方式发生:

1)部署人员以及映射一个安全觉得到运行环境中的一个用户组。调用的principal所属的用户组取自其安全属性。仅当principal所属的用户组由部署人员已经映射了安全角色,principal是在安全角色中。

2)部署人员已经映射安全角色到安全策略域中的principal名字。在这种情况下,调用的principal的名字取自其安全属性。仅当principal名字与安全角色一映射到的principal名字一样时,principal是在安全角色中。

57.web客户端可以使用一下机制之一向web服务器认证用户身份:

1HTTP基本认证(HTTP Basic Authentication

HTTP基本认证基于用户名和密码,是HTTP1.0规范中定义的认证机制。Web服务器请求web客户端认证用户。作为请求的一部分,web服务器传递realm(字符串)给要被认证的用户。Web客户端获取用户的用户名和密码并传给web服务器。Web服务器在指定的realm认证用户。

基本认证是不安全的认证协议。用户密码以简单的base64编码发送,且未认证目标服务器。

2HTTP摘要认证(HTTP Digest Authentication

HTTP基本认证类似,HTTP摘要认证也是基于用户名和密码认证的用户,但不像HTTP基本认证,HTTP摘要认证不再网络上发送用户密码。在HTTP摘要认证中,客户端发送单向散列的密码(和额外的数据)。尽管密码不在线路上发生,HTTP摘要认证需要对认证容器可用的明文密码等价物,以致容器可以通过计算与其的摘要验证接收到的认证者。Servlet容器应支持HTTP_DIGEST身份认证。

3HTTPS客户端认证(HTTPS Client Authentication

Web应用部署描述符包含登录表单和错误页面条目。登录界面必须包含用于输入用户名和密码的字段。这些字段必须分别命名为j_usernamej_password

当用户试图访问一个受保护的web资源,容器坚持用户的认证。如果用户已经通过认证则具有访问资源的权限,请求的web资源被激活并返回一个引用。

4)基于表单的认证(Form Based Authentication

当进行一个不受保护的传输时,基于表单的认证受制于一些与基本验证一样的相同的脆弱性。

当触发认证的请求在一个安全传输之上到达,或者登陆页面受制于一个CONFIDENTIAL user-data-constraint,登录页面必须返回给用户,并在安全传输之上提交到容器。

HttpServletRequest接口的login方法提供另一种用于应用控制它的登录界面外观的手段。

基于表单的登录和基于URLsession跟踪可以通过编程实现。基于表单的登录应该仅被用在当sessioncookieSSL session信息维护时。

为了进行适当的认证,登录表单的action总是j_security_check。该限制使得不管请求什么资源,登录表单都能工作,且避免了要求服务器指定输出表单的action字段。登录表单应该在密码表单字段上指定autocomplete="off"

58.安全约束是一种定义web内容包含的声明式方式。安全约束关联授权和/或在web资源上对HTTP操作的用户数据约束。安全约束,在部署描述符中由security-constraint表示,其包含以下元素:

1web资源集合(部署描述符中的web-resource-collection

2)授权约束(部署描述符中的auth-constraint

3)用户数据约束(部署描述符中的user-data-constraint

HTTP操作和网络资源的安全约束应用(即受限的请求)根据一个或多个web资源集合识别。Web资源集合包含以下元素:

1URL模式(部署描述符中的url-pattern

2HTTP methods(部署描述符中的http-methodhttp-method-omisssion元素)

授权约束规定认证和命名执行守约束请求的被许可的授权角色的要求。用户必须至少是许可执行受约束请求的命名角色中的一个成员。

特殊角色名“*”是定义在部署描述符中的所有角色名的一种简写。

特殊角色名“**”是一种用于任何授权的用户不受约束的角色的速记法。它表示任何授权的用户,不受约束的角色,被授权允许执行约束的请求。没有指定角色的授权约束表示在任何情况下不允许访问受约束请求。

授权约束包含以下元素:

1role name(部署描述符中的role-name

用户数据约束规定了在受保护的传输层连接之上接收约束的请求的要求,需要包含的强度由传输保障的值定义。INTEGRAL类型的传输保障用于规定内容完整性要求,且传输保障CONFIDENTIAL用于规定保密性要求的。传输保障“NONE”表示当容器通过任何包括不受保护的连接接收到请求时,必须接收此受约束的请求。容器可能在响应中抢救一个收报纸的传输保障(confidential transport guarantee)为INTEGRAL值。用户数据约束包括如下元素:

2transport guarantee(部署描述符中的transport-guarantee

如果没有授权约束应用到请求,容器必须接受请求,而不要求用户身份认证。如果没有用户数据约束应用到请求,当容器通过任何包括不受保护的连接接受到请求时,必须接收此请求。

59.url-patternHTTP方法以组合方式(即,在web-resource-collection中)出现在多个安全约束中,该约束(在模式和方法上的)是通过合并单个约束定义的。以相同的模式和方法出现在组合约束规则如下所示:

授权约束组合,其明确指定角色或通过"*"隐式指定角色,可产生单个约束的合并的角色名称作为许可的角色。一个命名觉得“**”的授权约束命名的或隐式的角色组合以允许任何授权的用户不受约束的角色。不包含授权约束的安全约束将与明确指定角色的或隐式指定角色的允许未授权访问的安全约束合并。授权约束的一个特殊情况是其没有指定角色,将与任何其他约束合并并覆盖它们的作用。这导致访问被阻止。

60.1web-app元素是一个Web应用程序的根部署描述符。此元素包含下列元素。这个元素有一个必须的属性version来指定部署描述符符合哪个版本的模式。此元素的所有子元素可以是任意的顺序。

2description元素提供了父元素的文本描述。

3displ-name元素包含一个简短的名称,目的是通过攻击显示,显示名称不必是唯一的。

4icon元素包含small-iconlarge-icon元素,为大型和小型GIFJPEG图标图片指定文件名,用于在GUI工具中标示父元素。

5distributable元素表示设定该Web应用程序适合部署到一个分布式的servlet容器中。

6context-param元素包含了Web应用程序的servlet上下文初始化参数的声明。

7filter元素声明了Web应用程序中的过滤器。该过滤器映射到一个servletfilter-mapping元素中的一个URL模式,使用filter-name的值来引用。过滤器在运行时可以通过FilterConfig接口中访问部署描述文件中声明的初始化参数。filter-name元素是过滤器的逻辑名称。他在Web应用程序中必须是唯一的。filter-name元素的元素内容不能为空。filter-class是过滤器的完全限定类名。init-param元素包含的名值对作为此过滤器的初始化参数。当指定可选的async-supported元素时,表示该过滤器支持异步请求处理。

8)容器使用filter-mapping决定哪个过滤器以什么样的顺序应用到请求。filter-name的值必须是部署描述文件中声明的过滤器中的一个。匹配的请求可以被指定为url-patternservlet-name

9listener表示应用程序监听器bean的部署属性。子元素listener-class声明应用程序中的一个类必须注册为Web应用程序监听器bean。它的值是监听器类的完全限定类名。

10servlet元素用于声明一个servlet。它包含一个servlet的声明性数据。jsp-file元素包含到以"/"开头的Web应用程序中一个JSP文件的完全路径。如果制定了jsp-file并且存在load-on-start元素,那么JSP应该被预编译和加载。servlet-name元素包含了servlet的规范名称。在Web应用程序中每个servlet的名称是唯一的。servlet-name元素的内容不能为空。servlet-class包含了servlet的完全类限定么。run-as元素指定用作一个组件执行的标识。它包含一个可选的description,和一个由role-name元素指定安全角色。load-on-startup元素表示该servlet应该被加载的顺序。如果该值是一个负整数,或不在该元素,容器自由选择什么时候加载这个servlet。如果该值是一个正整数或0,当应用部署后容器必须加载和初始化这个servlet。容器必须保证较小整数标记的servlet在较大整数标记的servlet之前加载。容器可以选择具有相同load-on-startup值的servlet的加载顺序。security-role-ref元素声明组件或部署组件的代码中的安全角色引用。它由一个可选的description,在代码中使用的安全角色名称(role-name),以及一个可选的到一个安全角色(role-link)的链接组成。如果没有指定安全角色,部署器必须选择一个合适的安全角色。当指定了可选的async-support元素,指示的servlet可支持异步请求处理。如果一个servlet支持文件上传功能和mime-multipart请求处理,通过描述文件中的multipart-config元素能够提供相同的配置。multipart-config元素可用于指定文件存储的位置,上传文件大小的最大值,最大请求大小和文件将写入磁盘之后的大小阈值。

11servlet-mapping元素定义了servletURL模式之间的映射。

12session-config元素定义了该Web应用程序的会话参数。子元素session-timeout定义了该Web应用程序中创建的所有会话的默认超时时间间隔。指定的超时时间必须使用分钟数表示。如果超时时间小于或等于0,容器将确保会话的默认行为永远不会超时。如果没有指定这个元素。容器必须设置它的缺省超时期限。

13mime-mapping定义了扩展名和MIME类型直接的映射。extension元素包含一个字符串描述的扩展名。

14welcome-file-list元素包含了一个有序的欢迎文件列表。子元素welcome-file包含一个用作缺省欢迎文件的文件名。

15error-page包含一个错误代码或异常类型到Web应用程序中资源的路径之间的映射。不过,error-codeexception-type元素可以省略来指定一个默认的错误页面。子元素exception-type包含了一个Java异常类型的完全限定名称。子元素location包含了web应用程序中相对于web应用程序干目录的资源位置。location的值必须以'/'开头。

16jsp-config用来提供Web应用程序中的JSP文件的全局配置信息。它有两个子元素,taglibjsp-property-grouptaglib元素可用来为Web应用程序中的JSP页面使用的标签库提供信息。

17security-constraint元素用于关联安全约束和一个或多个Web资源集合。子元素web-resource-collection确定安全约束应用到哪一些Web应用程序中资源的子集和这些资源的HTTP方法。auth-constraint表示拥护角色应该允许访问此资源集合。这里使用的role-name必须与该Web应用程序定义的其中一个security-role元素的role-name对应,或是指定的保留role-name“*”对应。这是一个表示web应用程序中的所有角色的紧凑语法。如果“*”和角色名都出现了,容器会将此解析为所有角色。如果没有定义觉得,不允许任何用户访问由包含security-constraint所描述的Web应用程序的部分。当容器确定访问时匹配角色名称是区分大小写的。user-data-constraint表示客户端和容器之间的通信数据如何受到子元素transport-guarantee的保护。transport-guarantee的合法值是NONEINTEGRALCONFIDENTIAL之一。

18login-config用于配置应该使用的验证方法,可用于此应用程序的领域名,以及表单登录机制所需要的属性。子元素auth-methodWeb应用程序配置验证机制。该元素的内容必须是BASICDIGESTFORMCLIENT-CERTvendor-specific验证模式。realm-name表示为Web应用程序选择用于验证模式的领域名。form-login-config指定应该用于基于表单登录的登录和错误页面。如果不使用基于表单的登录方式,这些元素将被忽略。

19security-role定义了一个安全角色。子元素role-name指定安全角色的名称。该名称必须符合NMTOKEN的词法规则。

20env-entry声明了一个应用程序的环境入口。子元素env-entry-name包含部署组件环境入口的名称。这个名称是一个相对于java:comp/env上下文的JNDI名称。在部署组件中该名称必须是唯一的。env-entry-type包含了应用程序代码所期望的环境入口值的Java类型完全限定名。子元素env-entry-value指定部署组件的环境入口值。该值必须是一个String,对指定的使用一个Stringjava.lang.Character类型作为参数的构造器有效。可选的injection-target元素用来定义把指定的资源注入到字段或JavaBean属性。injection-target指定了类中应该被注入资源的类和名称。injection-target-class制定了注入目标的完全限定类名称、injection-target-name制定了指定雷中的目标。首先把查找目标作为一个JavaBean属性名称。如果没有找到,则把查找目标作为一个字段名。在类初始化期间通过调用目标属性的set方法或给名称字段设置一个值将指定的资源注入到目标。如果环境入口指定了一个injection-target,那么env-entry-type可以省略或必须与注入目标的类型匹配。如果没有指定injection-target,那么需要指定env-entry-type

21ejb-ref声明了一个对企业beanhome应用。ejb-ref-name制定了引用企业bean的部署组件代码中使用的名称。ejb-ref-type是引用的企业bean期望的类型,它可以是EntitySessionhome定义了引用的企业beanhome接口的完全限定名称。remote定义了引用的企业beanremote接口的完全限定名称。ejb-link指定了连接到企业bean的一个EJB应用。injection-target元素可以用于定义指定的企业bean注入到一个组件的字段或属性。

22ejb-local-ref声明了对企业bean的本地home引用。local-home定义了企业bean的本地home接口的完全限定名称。local定义了企业bean的本地接口的完全限定名称。

23service-ref声明了一个对Web service的引用。service-ref-name声明了用于查找Web service模块组件的逻辑名称。建议所有service的引用名称以/service/开头。service-interface定义了客户端依赖的JAX-WS Service接口的完全限定类名称。在大多数情况下,这个值是javax.xml.rpc.Service。也可以指定一个JAX-WS生成的服务接口类。wsdl-file元素包含了WSDL文件的URI位置。这个位置相对于模块根目录。jaxrpc-mapping-file包含了描述应用程序使用的Java接口和wsdl-file中的WSDL描述之间的JAX-WS映射的文件名。这个文件名是一个模块文件中的相对路径。

24resource-ref元素包含了部署组件对外部资源的引用声明。res-ref-name指定了一个资源管理器连接工程引用的名称。这个名称是一个相对于java:com/env上下文的JNDI名称。在部署文件中这个名称必须是唯一的。res-type元素指定数据源的类型。该类型是一个希望由数据源实现的Java语言类或接口的完全限定名。res-auth指定部署组件代码是否以编程方式注册到资源管理器,或容器是否将代表的部署组件注册到资源管理器。如果是第二种情况,容器使用部署器提供的注册信息。res-sharing-scope指定了通过给定的资源管理器连接工厂引用获取的连接是否可以共享。如果制定了这个值,它必须是ShareableUnshareable。可选的injection-target元素用于定义把指定的资源注入到字段或JavaBean属性。

25resource-env-ref包含了部署组件和对部署组件环境中的资源有关的关联对象的引用。resource-env-ref-name指定了资源环境引用的名称。它的值是部署组件代码中使用的环境入口名称,它是一个相对于java:comp/env上下文的JNDI名称,并且在部署组件中必须唯一的。resource-env-ref-type制定了资源环境引用的类型。它是一个Java语言类或接口的完全限定名。可选的injection-target元素用于定义把指定的资源注入到字段或JavaBean属性。必须提供resource-env-ref-type除非指定了注入目标,在这种情况下,将使用目标的类型。如果两者都指定,该类型必须与注入目标的类型兼容。

26message-destination-ref元素包含了部署组件和对部署组件环境中的资源有关的目标的引用声明。message-destination-ref-name元素制定了一个目标引用的名称,它的值是部署组件代码中使用的环境入口名称。

27message-destination指定消息的目标。这个元素所描述的逻辑目标由部署映射到物理目标。message-destination-name元素指定了消息目标的名称。该名称在部署文件的消息目标名称中必须是唯一的。

28local-encoding-mapping-list包含了语言环境和编码直接的映射。由子元素locale-encoding-mapping指定。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章