zoukankan      html  css  js  c++  java
  • 第三章 Request(JavaTM Servlet 规范3.1 )

    The Request  请求

    请求对象包装了所有来自客户端请求的信息。在HTTP协议中,这些信息在HTTP头和请求消息体中从客户端传输到服务器端。

     

    3.1 HTTP Protocol Parameters  HTTP 协议参数

     

    Servlet 的请求参数都是字符串,它们作为请求的一部分从客户端被发送到 servlet 容器。当请求是 HttpServletRequest 对象,并且满足第 24 页 “当参数可用”的条件时,容器从 URI 请求字符串和被 POST 的数据中计算这些参数。这些参数被存储为一系列的键值对。任何给定的参数名可能存在多个参数值。可以用下面的 ServletRequest 接口的方法来访问参数:

    ■ getParameter


    ■ getParameterNames

    ■ getParameterValues

    ■ getParameterMap

    getParameterValues 方法返回一个包含相关联的参数名的所有参数值的字符串对象数组。getParameter 返回的值必须是 getParameterValues 返回的字符串对象数组的第一个值。getParameterMap 返回一个请求参数的 Map,参数名称作为键,参数值作为map的值。

    来自请求字符串和 post 体的数据被集中在请求参数集中。请求字符串数据在 post 体数据之前被呈现。例如:如果一个请求由一个请求字符串 a=hello 和 一个 post 体 a=goodbye&a=world 组成,参数集合的结果将被排序为 a=(hello,goodbye,world)。

    路径参数是 GET 请求(定义在HTTP 1.1)的一部分,不被这些API公开。它们必须从 getRequestURI 或 getPathInfo 方法返回的字符串值中解析。

     

    3.1.1 When Parameters Are Available 当参数可用

    必须先满足下面的条件,POST 表单数据才会被计算到参数集中:

    1. 请求是一个HTTP 或者 HTTPS 请求。
    2. 请求的方法是 POST。
    3. 内容类型是 application/x-www-form-urlencoded。
    4. servlet 已经在请求对象上执行了 getParameter 系列方法中的一个初始化调用。

    如果这些条件没有满足并且 POST 表单数据不包含在参数集合中,通过请求对象的输入流,POST数据必须仍然对 servlet 可用。如果这些条件被满足,POST表单数据将不再可以通过从请求对象输入流直接读取而使用。

     

    3.2 File upload 文件上传

    当数据被当做 multipart/form-data 传送时, Servlet 容器允许文件上传。


    当下面的任一条件被满足时,servlet 容器提 供multipart/form-data 处理。

    • 处理请求的 servlet 被在 8.1.5 节中定义的@MultipartConfig 标注。
    • Deployment descriptors contain a multipart-config element for the servlet handling the request. 
How data in a request of type multipart/form-data is made available depends on whether the servlet container provides multipart/form-data processing: 

    • 部署描述符包含为 servlet 处理请求的 multipart-config 元素。 请求中 multipart/form-data 类型的数据如何变得可用,依赖于 servlet 容器是否提供 multipart/form-data 处理:

     ■ 如果 servlet 容器提供 multipart/form-data 处理,数据通过  HttpServletRequest 的下列方法变得可用:

    • public Collection<Part> getParts() 

    • public Part getPart(String name)

    每个 part 通过 Part.getInputStream 方法提供访问与之关联的 headers,content type 和 内容。

     

    For parts with form-data as the Content-Disposition, but without a filename, the string value of the part will also be available through the getParameter and getParameterValues methods on HttpServletRequest, using the name of the part.

    带有 form-data 的 parts 作为 Content-Disposition,即使没有文件名,part 的字符串值也可以用 part 的名字(作为参数)通过 HttpServletRequest 的 getParameter 和 getParameterValues 方法使用。

     

    ■ 如果 servlet 容器没有提供 multi-part/form-data 处理,数据将通过 HttpServletReuqest.getInputStream 来使用。

     

    3.3  Attributes  属性

    属性是与请求关联的对象。属性可以被容器设置来表达哪些不能通过 API 表达的信息,或者被 servlet 设置用来与另外的 servlet(通过 RequestDispatcher)通信。属性可以通过 ServletRequest 接口的以下方法来访问:

    ■ getAttribute

    
■ getAttributeNames

    ■ setAttribute

    
            仅有一个属性值与一个属性名关联。以 java. 和 javax. 为前缀的属性名在该规范中被保留定义。相似的,以sun.,com.sun.,oracle 和 com.oracle 为前缀的属性名被 Oracle 公司保留定义。建议属性集中的所有属性使用与 Java 编程语言规范 1 中建议的用反向域名命名包名那样来命名属性名。:(

     

    3.4  Headers

    servlet 可以通过下面 HttpServletRequest 接口的方法访问 HTTP 请求的头:

    
■ getHeader

    
■ getHeaders


    ■ getHeaderNames 


    getHeader 方法返回给定头名称的头。在一个 HTTP 请求中,相同名称可能有多个头,例如 Cache-Control 头。如果同一个名称有多个头,getHeader 方法返回这个请求中(该名称)的第一个头。getHeaders 方法允许访问特定的头名称的头的所有值,返回一个字符串对象的枚举。头可能包含 int 或者 Date 数据的字符串表示。下面的 HttpServletRequest 接口的便捷方法提供访问这些格式的头数据:

    ■ getIntHeader

    ■ getDateHeader

    如果 getIntHeader 方法不能转换头值为 int ,将会抛出NumberFormatException。如果 getDateHeader 方法不能转换头为一个 Date 对象,将会抛出IllegalArgumentException。

     

    3.5 Request Path Elements  请求路径元素

    引导 servlet 服务请求的请求路径有几个重要的组成部分。下面的元素从 request URI 路径中获得并且通过请求对象公开:

    • Context Path: 与此 servlet 所属的 ServletContext 关联的路径前缀。如果此上下文是Web服务器的URL命名空间的基础为根的“默认”上下文,此路径为空字符串。否则,如果此上下文不以服务器命名空间基础为根,此路径以 “/” 开始,但不以“/”结束。

    • Servlet Path: 此路径部分直接与被此请求激活的映射对应。此路径以’/’字符开始,除非此请求匹配 ‘/*’ 或“”,此时此路径是空字符串。

    • PathInfo:  请求路径的这部分既不是 Context Path 也不是 Servlet Path 的一部分。如果没有额外的路径就是 null,否则就是以 “/” 开头的字符串。

    HttpServletRequest 接口中的下列方法可以访问这些信息:

    ■ getContextPath

    ■ getServletPath

    ■ getPathInfo 


    值得注意的是,除非请求 URI 和 路径部分之间的 URL 编码的不同,下面的等式永远为true:

    requestURI = contextPath + servletPath + pathInfo

    给出几个例子来理清上面的观点:

    3-1 例子 上下文设置

    Context Path                    /catalog

     

    Servlet Mapping                            Pattern:/lawn/*

                                                       Servlet: LawnServlet

     

    Servlet Mapping                            Pattern:/garden/*

                                                       Servlet: GardenServlet

     

    Servlet Mapping                             Servlet: *.jsp

                                                        Servlet: JSPServlet

    The following behavior is observed:

    遵守以下行为:

    3-2 遵守路径元素行为

     

    /catalog/lawn/index.html                ContextPath: /catalog

                                                        ServletPath: /lawn

                                                        PathInfo: /index.html

     

    /catalog/garden/implements/         ContextPath: /catalog

                                                       ServletPath: /garden

                                                       PathInfo: /implements/

     

    /catalog/help/feedbak.jsp               ContextPath: /catalog

                                                        ServletPath: /help/feedback.jsp

                                                        PathInfo: null

     

    3.6 Path Translation Methods 路径转换方法

    有两个便捷方法让开发者获得一个指定路径的与之等价的文件系统路径。这些方法是:

    ■ ServletContext.getRealPath

    
■ HttpServletRequest.getPathTranslated

    getRealPath 方法使用一个字符串参数并返回一个字符串表示路径在本地文件系统中的对应文件。getPathTranslated 方法计算请求的 pathInfo 的真实路径。

    在 servlet 容器不能为这些方法确定一个合法文件路径情况下,比如当 Web应用从一个文档,一个本地不能访问的远程文件系统上,或在数据库里执行时,这些方法必须返回null。只有在容器已经将JAR文件中META-INF/resources目录下的资源从包含他们的JAR文件解压缩,这种情况下调用 getRealPah() 时,必须返回解压缩之后的位置。(Resources inside the META-INF/resources directory of JAR file must be considered only if the container has unpacked them from their containing JAR file when a call to getRealPath() is made, and in this case MUST return the unpacked location.)

     

    3.7 Non Blocking IO  非阻塞IO

    Web容器中的非阻塞请求处理有助于改善提升Web容器伸缩性不断增长的要求,增加Web容器同时处理的连接的数量。容器的非阻塞IO允许开发者在数据可读时读取数据,可写时写入数据。非阻塞IO只有 在Servlets 和 Filters 进行异步请求处理时和升级处理时发挥作用。否则调用 ServletInputStream.setReadListener 或 ServletOutputStream.setWriteListener时必须抛出 IllegalStateException。

    ReaderListener 为非阻塞 IO 提供了如下回调方法:

    ■ ReadListener

    • onDataAvailable(). 当可以从传入的请求流中读取数据时 ReadListener 的 onDataAvailable 方法将被调用。当数据可读时,容器第一次调用这个方法。当且仅当在下面描述的 ServletInputStream 的  isReady 方法返回 false,容器将随后调用 onDataAvailable 方法。

    • onAllDataRead(). 当你为注册了此 listener (ReadListener)  的ServletRequest 读取完所有的数据时,onAllDataRead 将被调用。

    • onError(Throwable t). 当处理请求时如果有任何错误或者异常发生,onError方法将会被调用。Servlet 容器必须以线程安全的方式访问 ReadListener的方法。除了上面定义的  ReadListener ,下面的方法被添加到 ServletInputStream 类:

    ■ ServletInputStream 


    • boolean isFinished(). 与请求关联的 ServletInputStream 的所有数据已经读取完毕时,isFinished 返回 true,否则返回 false。

    • boolean isReady(). 如果数据可以被无阻塞读取时 isReady 返回 true。如果没有数据可以被无阻塞读取,它返回false。如果 isReady 返回 false ,调用读方法是非法的,必须抛出 IllegalStateException。

    • void setReadListener(ReadListener listener). 设置上面定义的 ReadListener,调用它以非阻塞方式读取数据。一旦该 listener 与给定的 ServletInputStream 关联,当数据可读时,所有的数据被读取或处理请求时产生一个错误,容器将调用 ReadListener 上的方法。注册一个 ReadListener 将开启无阻塞IO。那时切换到传统的阻塞IO是非法的,必须抛出 IllegalStateException。在当前请求范围内接下来调用 setReadListener 是非法的,必须抛出 IllegalStateException。


    3.8 Cookies

    HttpServletRequest 接口提供了 getCookies 方法获取请求中的 cookie 数组。这些 cookie 是客户端发起的从客户端发送到服务器的每个请求上数据。典型地,客户端发回的作为 cookie 的一部分的仅有信息是 cookie 名和 cookie 值。当 cookie 被发送到浏览器时也可以设置其他 cookie 信息,例如:注释,将不会被返回(服务器)。本规范也允许 cookies 成为 HttpOnly cookies。HttpOnly  cookies 意味着客户端不能将它们向客户端脚本代码公开(除非客户知道查找这个属性,否则它不会被过滤掉)。HttpOnly cookies 的使用帮助减轻某些特定种类的跨站脚本攻击。

     

    3.9 SSL Attributes  SSL 属性

    如果请求在一个安全协议上传输,比如 HTTPS,此信息必须通过 ServletRequest 接口的 isSecure 公开。Web容器必须向 servlet 开发者公开下面的属性:

    表3:协议属性

    Attribute                                        Attribute Name                                                Java Type

     

    cipher suite                                    javax.servlet.request.cipher_suite                     String

    密码套件

     

    bit size of the algorithm                  javax.servlet.request.key_size                           Integer

    算法位大小

     

    SSL session id                                javax.servlet.request.ssl_session_id          String

     

    如果有一个SSL证书与请求关联,它必须通过 servlet 容器作为一个  java.security.cert.X509Certificate 类型的对象数组向 servlet 编程者公开,并且可以通过 ServletRequest 的 javax.servlet.request.X509Certificate 的属性访问。

    这个数组的顺序被定义为按照信任程度升序排列。链中的第一个证书是客户端设置的,下一个是用来验证第一个的,以此类推。

     

    3.10 Internationalization 国际化

    客户端可以有选择的提示Web服务器以何种语言来响应。这个信息可以通过客户端使用 Accept-Language 头 和其他在 HTTP/1.1 描述的机制来沟通。

    ServletRequest 接口提供了下面的方法来确定发送者的首选Locale:

    ■ getLocale

    ■ getLocales

    getLocale 返回客户端希望接受的内容的首选Locale。参考 RFC 2616 (HTTP/1.1) 的14.4 节获取关于 Accept-Language 头必须怎样被解释来确定客户端的首选语言的更多信息。

    getLocales方法将返回一个 Locale 对象的枚举,从首选 Locale 顺序递减,这些 Locales 是被客户端所接受的。

    如果客户端没有指明首选Locale,getLocale 方法返回的 Locale 必须是 servlet 的默认 Locale,getLocales 方法必须返回只包含此默认 Local 的单元素枚举。

     

    3.11     Request data encoding 请求数据编码

    目前,很多浏览器不使用 Content-Type 头发送字符编码,而是根据读取 HTTP 请求确定字符编码。如果客户端请求没有指明请求的默认编码,容器用来创建请求 reader 和解析 POST 数据的默认编码必须是“ISO-8859-1”。但是,为了提醒开发者,在这种情况下(客户端没有指定字符编码),客户端发送字符编码的失败,容器从 getCharacterEncoding 方法返回null。

    如果客户端没有设置字符编码,并且请求数据没有使用上面描述的默认方式编码,而是使用不同的编码方式,将会产生乱码问题。为了弥补这个情况,一个新的方法 setCharacterEncoding(String enc) 被添加到 ServletRequest 接口。开发者可以通过调用这个方法覆盖容器提供的字符编码。必须在解析任何 POST 数据或读取任何请求输入之前调用。这个方法一旦被调用,不会影响已经读取的数据的编码。


     

    3.12     Lifetime of the Request Object 请求对象的生命周期

    每个请求对象只有在 servlet 的 service 方法或者 filter 的 doFilter 方法范围中有效,除非此组件的异步处理启用并且请求对象的 startAsync 方法被调用。在这种情况下,异步处理将发生,请求对象将保持有效直到 AsyncContext 的 complete 方法被调用。为了避免创建请求对象的性能消耗,容器通常反复利用 请求对象。开发者必须注意,不建议在上述范围之外保持没有调用 startAsync 方法的请求对象,因为它可能产生不确定的结果。

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


  • 相关阅读:
    第60届IMO 第5题
    第31届IMO 第2题
    洛谷【P1595 信封问题】 题解
    洛谷【P2022 有趣的数】 题解
    洛谷【P5004 专心OI
    04-----jQuery的属性操作
    03-----jQuery动画效果
    02-----jQuery的选择器
    01-----jQuery介绍
    17-----案例
  • 原文地址:https://www.cnblogs.com/whilliy/p/5685079.html
Copyright © 2011-2022 走看看