Reading – Java™ Servlet Specification Version 2.4 – Overview

Loading and Instantiation

对 servlet 的装载和初始化可能在容器启动时进行, 也可能推迟到容器认为需要该 servlet 处理请求时进行.

Number of Instances

如果 servlet 是在非分布式环境中, servlet container 须确保每个 servlet 只有一个实例.
但也有例外, 那就是实现了 SingleThreadModel 的 servlet, servlet container 可能会为该 servlet 实例化多个实例, 以应付大量请求.

如果 servlet 是在分布式环境中, servlet container 须确保每个虚拟机中每个 servlet 只有一个实例. 不过也有例外, 同上.

Thread Safety

规范明确提出, 不要在 request lifecycle 外使用 request 和 response objects

End of Service

规范不要求 servlet container 长时间保持 servlet 活跃状态, 也就是说有的 servlet container 可能会在 servlet 长时间无请求访问时调用它的 destroy 方法进行销毁, 释放资源. 但在调用 destroy 方法之前, servlet container 会让所有调用该 servlet service 方法的线程执行完毕, 或者超过了服务器定义的时间限制才去调用 destroy. destroy 调用之后, servlet container 会释放这个 servlet instance, 让虚拟机进行垃圾收集.

Scope of a ServletContext Interface

在一个容器中, 一个 web app 只能有一个ServletContext 实例. 在分布式环境下, 每个 JVM 中一个 web app 只能有一个ServletContext 实例.

Servlets in a container that were not deployed as part of aWeb application are implicitly part of a “default” Web application and have a default ServletContext. In a distributed container, the default ServletContext is non-distributable and must only exist in one JVM.

Context Attributes in a Distributed Container

Context attributes 只能在创建它们的 JVM 中访问到, 这样, 在分布式环境中就难以实现共享. 当信息需要在分布式容器中运行的 servlets 间共享时, 这些信息应该放到 session, 数据库, 或者 Enterprise JavaBeans 中.

Access Resources Via ServletContext APIs

ServletContext interface 提供了访问 web app 中静态内容文档的方法, 包括 HTML, GIF, and JPEG files文件, 这些方法是:

• getResource
• getResourceAsStream

getResource and getResourceAsStream 方法接收以 “/” 打头的字符串作为参数, 这个参数给出了资源相对于 context root 的路径. 文档可能在服务器系统上, 在一个 WAR 文件中, 在一个远端服务器上, 或者在其它某个位置.
这些方法不是用来获得动态内容的. 例如, getResource(“/index.jsp”) 会返回 JSP source code 而不是经处理的输出结果.
使用 getResourcePaths(String path) 方法能得到 web app 中的 resource 列表.

Multiple Hosts and Servlet Contexts

Web servers 可能支持多个逻辑主机, 在一个服务器上共享同一个 IP 地址. 这种能力有时也称为 “virtual hosting”. 在这种情形下, 每个逻辑主机必须具有它自己的 servlet context 或者 set of servlet contexts. 不能在 virtual hosts 之间共享 Servlet contexts.

Reloading Considerations

虽然不要求容器提供商必须实现 class reloading 以方便开发, 但如果有这么实现的话, 那么必须确保所有 servlets, 和这些 servlets 可能用到的 classes, 都是在同一 class loader scope 内被装载. 这个要求是为了保证应用程序的行为符合开发人员的预期. As a development aid, the full semantics of notification to session binding listeners should be supported by containers for use in the monitoring of session termination upon class reloading.
Previous generations of containers created new class loaders to load a servlet, distinct from class loaders used to load other servlets or classes used in the servlet context. This could cause object references within a servlet context to point at unexpected classes or objects, and cause unexpected behavior. The requirement is needed to prevent problems caused by demand generation of new class loaders.

Temporary Working Directories

对每个 servlet context 都要求有一个临时目录. Servlet containers 必须为每个 servlet context 提供一个私有临时目录, 使之通过 javax.servlet.context.tempdir context attributeand 可用. 关联到这个 attribute 的 object 必须是 java.io.File 类型.
不要求容器在重启之时还维护临时目录内的内容, 但要求确保一个 servlet context 的临时目录内容对运行在相同 servlet container 中的其它 web apps 的 servlet contexts 不可见.

HTTP Protocol Parameters of Request

getParameterValues 方法返回一个参数的多个值(数组形式).
如果参数有多个值, 那么 getParameter 方法返回的将是通过 getParameterValues 方法所返回数组的第一个值.
QueryString 和 post body 中的参数都将一起通过 getParameter 等方法集中展现, 但 QueryString 中的参数总是优先于 post body 中的参数. 例如, 如果一个请求由一个查询字符串 a=hello 和一个 post body a=goodbye&a=world 组成, 那么这些参数合在一起将按照 a=(hello, goodbye, world) 顺序排列.

When Request Parameters Are Available

The following are the conditions that must be met before post form data will be populated to the parameter set:

1. The request is an HTTP or HTTPS request.
2. The HTTP method is POST.
3. The content type is application/x-www-form-urlencoded.
4. The servlet has made an initial call of any of the getParameter family of methods on the request object.

If the conditions are not met and the post form data is not included in the parameter set, the post data must still be available to the servlet via the request object’s input stream. If the conditions are met, post form data will no longer be available for reading directly from the request object’s input stream(对这句话甚是怀疑, 至少tomcat觉得就不是这么实现的, 要亲自检验一下才行).

Request Attributes

以 “java.” 和 “javax.” 开头的 attribute name 是由规范所保留, 类似的, 以 “sun.”, 和 “com.sun.” 开头的 attribute names 被 Sun 微系统公司所保留.

Request Headers

getHeader 方法返回一个 header 值. 同一 header name 可能有多个 headers, 例如 Cache-Control headers. 如果同一名字有多个 headers, getHeader 方法返回 request 中的第一个 header. getHeaders 方法允许访问与某个 header name 相关联的所有 header values, 返回的是一个字符串的 Enumeration 对象.

Request Path Elements

通过 HttpServletRequest interface 的如下方法可访问到上述信息:

• getContextPath
• getServletPath
• getPathInfo

需要注意的是, 除了由于 URL encoding 导致 request URI 和路径各部分不同外(except for URL encoding differences between the request URI and the path parts), 下面这个等式总是成立:
requestURI = contextPath + servletPath + pathInfo

Path Translation Methods

通过如下方法可得到文件系统路径

当 Servlet container 不能确定文件的有效路径时,如 web app 使用的是 archive, 一个远程文件系统而非本地, 或数据库中的文件时,这些方法必须返回 null.

Cookies

在客户端发起的每次请求中都会带有 cookie 数据. 通常客户端发给服务器的 cookie 只有 cookie name 和 cookie value, 其它属性通常不会发送到服务器.

SSL Attributes

如果请求是通过安全协议传输,  如 HTTPS, 那么 ServletRequest 接口的 isSecure 方法必须提供这个信息. Web container 必须提供如下 attributes 给编程人员:

cipher suite                                              javax.servlet.request.cipher_suite                 String
bit size of the algorithm                      javax.servlet.request.key_size                         Integer

If there is an SSL certificate associated with the request, it must be exposed by the servlet container to the servlet programmer as an array of objects of type java.security.cert.X509Certificate and accessible via a ServletRequest
attribute of javax.servlet.request.X509Certificate.
The order of this array is defined as being in ascending order of trust. The first certificate in the chain is the one set by the client, the next is the one used to authenticate the first, and so on.

Internationalization

ServletRequest 接口提供如下方法可得知请求发起人偏爱何种 locale:

• getLocale
• getLocales

getLocale 返回的是客户端最偏爱的 locale. getLocales 返回的则是客户端偏爱的所有 locales 的 Enumeration, 以最爱到次之的顺序排列.

如果客户端没有指定偏爱的 locale, 则 getLocale 方法返回的 locale 必须是 servlet container 的默认 locale, getLocales 方法必须返回只有一个默认 locale 的 enumeration.

Request data encoding

目前, 很多浏览器不使用 Content-Type header 发送字符编码信息, 由 web container 自主决定使用何种字符编码读取请求(leaving open the determination of the character encoding for reading HTTP requests). 如果客户端请求没有指定字符编码, 那么容器必须使用 “ISO-8859-1” 作为默认字符编码去创建 request reader 和解析 POST data. 然而, 为了告诉开发人员客户端没有发送字符编码信息, 容器会为 getCharacterEncoding 方法返回 null.
如果客户端没有设置字符编码且 request data 使用非默认字符编码进行编码, 将发生乱码(breakage can occur). 为纠正这种情况, ServletRequest interface 中增加了一个新方法 setCharacterEncoding(String enc). 开发人员可以通过调用这个方法覆盖掉由容器所提供的字符编码. 这个方法必须在解析 post data 或读取 request input stream 之前调用(It must be called prior to parsing any post data or reading any input from the request). Calling this method once data has been read will not affect the encoding.

Lifetime of the Request Object

每个 request object 只在 servlet service 方法范围内有效, 或者在 filter 的 doFilter 方法内有效. Containers 常常回收 request objects 以便避免影响到 request object 的创建(avoid the performance overhead of request object creation). 开发人员必须认识到在上述提到的范围外持有到 request object 的引用是不推荐的, 因为这可能会导致一些不确定的结果.

By javafuns on December 22, 2008 at 21:43 · Views: 1,352 · Permalink · RSS
Categorized in: Java · Tagged with: ,
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

Leave a Reply


  • Highest Rated

  • My PicasaPhotos

    IMG_0559.JPG

    2aed7a17aa9c1a124a90a720.jpg

    IMG_0682.JPG

  • RSS My del.icio.us

  • My RSS