Servlet Specification V2.4——SRV.4 The Request

SRV.4 The Request

        Request对象压缩了来自客户端request的所有信息。根据HTTP协议,这些信息存放在HTTP header和request的message body中,从客户端传送至服务器。

 

 

SRV.4.1 HTTP Protocol Parameters

        作为request的一部分,servlet的request参数是client发送给servlet container的字符串。当request是一个HttpServletRequest对象,并且满足SRV4.1.1 When Parameters Are Available的条件,container会从URI查询字符串和POST-ed数据中取得参数。
        参数以name-value键值对的形式被存储。任何给定的参数名都可以被赋予多个参数值。下面是 ServletRequest接口用来存取参数的方法:

  • getParameter

  • getParameterNames

  • getParameterValues

  • getParameterMap

        getParameterValues方法返回了一个包含了与指定参数名称绑定的所有参数值String对象数组。getParameter方法的返回值一定是getParameterValues方法返回的String对象数组中的第一个String。getParameterMap方法返回了以java.util.Map表示的request中的所有参数,其中key为参数名称,map value是参数值。
        来自查询字符串的数据和post body都存放在request的参数集合中。查询字符串出现在post body之前。例如,一个request的query string为a=hello,post body里有a=goodbye&a=world,那么结果参数集合就会以a=(hello, goodbye, world)的顺序呈现。
        作为GET request的一部分(由HTTP1.1定义),路径参数并不被这些API暴露。他们必须通过getRequestURI方法或getPathInfo方法返回的String values被分析。

 

SRV.4.1.1 When Parameters Are Available

以下条件是在post form数据在被移至参数集合之前必须满足的条件:

  1. request是HTTP/HTTPS request

  2. HTTP method是POST。

  3. content type是application/x-www-form-urlencoded。

  4. servlet已经对request对象中所有getParameter可以得到的参数做了初始化调用。

        如果条件不满足并且post form数据并没有包含在参数集合中,对于servlet来说,post数据仍然是可用的,可以通过request对象的输入流获得(the post data must still be available to the servlet via the request object's input stream)。当条件满足,post form数据将不能再从request对象的输入流中直接读取。

 

 

SRV.4.2 Atributes

        attribute是绑定在request上的一些对象。Attribute可以由container set到request中,用来表达不能通过API表达的信息;或者由servlet set到request中,用来和其他servlet通讯(通过RequestDispatcher)。Attribute可以通过ServletRequest接口的以下方法来存取:

  • getAttribute

  • getAttributeNames

  • setAttribute

        attribute的value和name是一一对应的。
        根据规范的定义,前缀为{[java.], [javax.]}的attribute是被本规范保留的。同样的,前缀为{[sun.], [com.sun.]}的attribute被sun公司保留。关于所有放到attribute集合中的attribute的命名,一般建议与Java Programming Language Specification关于package命名建议保持一致,也就是域名反序排列。

 

 

SRV.4.3 Header

Servlet可以通过HttpServletRequest接口的以下方法存取HTTP request的header信息:

  • getHeader

  • getHeaders

  • getHeaderNames

        getHeader方法返回以入参为名称的header。多个header可以有同样的名字,例如,Cache-Control headers,在HTTP request中。如果多个header拥有相同的名字,getHeader方法返回request中第一个header。getHeaders方法允许存取以入参为header name的所有的header值,返回一个String对象的枚举类型。
        Headers可以包含int或者Date类型数据的String表达。以下是HttpServletRequest接口中可以以某种格式存取header数据的便捷方法:

  • getIntHeader

  • getDateHeader

        如果getIntHeader方法不能把header中的值转换成int类型的数据,就会抛出NumberFormatException。如果getDateHeader方法不能把header转换成Date类型的数据,就会抛出IllegalArgumentException。

 

 

 

SRV4.4 Request Path Elements

        引导servlet处理request的request路径由很多重要的部分组成。下面的元素通过request对象获取request URI路径再被解析而得到:

  • Context Path:context path前缀与当前servlet所属的servlet context相关。如果这个context是位于web server的URL name space的根节点的“默认”context,那这个path就是一个空字符串。否则,如果context部位於server的URL name space根节点,那context path就是以字符'/'开始,以字符'/'结束但包括'/'的一段字符。

  • Servlet Path:servlet path是直接激活request与servlet的映射的部分。以字符'/'开始,除了在request匹配'/*'模式的情况下。在这种情况下,它是个空字符串。

  • PathInfo:这部分的request path既不是context path,也不是servlet path。它要么在没有额外的path时为空,要么就是以'/'开头的字符串。

        以下为HttpServletRequest的一些方法,用来存取这些信息:

  • getContextPath

  • getServletPath

  • getPathInfo

        重点需要注意的是,除了URL编码不同于request URI和路径部分,以下的方程式为恒等式:requestURI =  contextPath + servletPath + pathInfo

        以下是一些例子,用来阐明以上的要点:见图SRV.4.4 - 01.png,SRV.4.4 - 02.png

 

 

SRV.4.5 Path Translation Methods

        开发者可以地通过API中的两个便捷方法来获得等价于特定路径的文件系统路径(obtain the file system path equivalent to a particular path)。这些方法是:

  • ServletContext.getRealPath

  • HttpServletRequest.getPathTranslated

        getRealPath方法以一个String为参数,返回一个代表了本地文件系统上的文件的String表达形式,一个符合文件位置的路径。getPathTranslated方法计算了request的pathInfo的真实路径。
        在servlet container不能为这些方法找到一个和法文件路径的情况下,比如web应用程序从一个存档文件中被执行,在本地无发存取的远程文件系统上,或者在数据库中,这些方法会返回null。

 

 

SRV.4.6 Cookies

        HttpServletRequest接口提供了getCookies方法来获得request中现存的cookie数组。这些cookie是每一次客户端发起请求时client发起送至server的的数据。一般来说,作为cookie的一部分client返回的唯一信息就是cookie的name和value。其他在cookie被发送至浏览器是可以被set的cookie属性,比如注释,并不是典型的返回信息。

 

 

SRV.4.7 SSL Attributes

        如果request通过安全协议传送,就像HTTPS,这个信息必须通过ServletRequest接口的isSecure方法被呈现。Web container一定会呈现以下的attribute给servlet程序员:见图SRV.4.7 - 01.png。

        如果有一个SSL证书与request相关联,它一定会被servlet container作为java.security.cert.X509Certificate类型的对象数组展示给servlet开发者,并且通过ServletRequest的attribute javax.servlet.request.X509Certificate被访问。
        数组定义的书序是配用来验证的列表(The order of this array is defined as being in ascending order of trust)。数组中的第一个证书是被客户端set的,接下来的一个用来验证第一个证书,这样一直往后排。

 

 

SRV.4.8 Internationalization

        如果愿意,客户端可以选择以它喜欢的语言获得从web服务器返回的response。服务器可以使用Accept_Language header从客户端获得这些信息并进行通讯,通过使用HTTP/1.1规范中描述的其他机制。(This information can be communicated from the client using the Accept-Language header along with other mechanisms described in the HTTP/1.1 specification)。ServletRequest接口提供了一下方法来决定request的语言偏好(the preferred locale):

  • getLocal

  • getLocales

        getLocal方法会返回客户端设置的response content的语言偏好(the preferred locale)。参见RFC 2616(HTTP/1.1)的14.4节以获取更多关于Accept-Language header如何必须解析来决定客户端的语言偏好(how the Accept-Language header must interpreted to determine the preferred language of the client)。
        getLocales方法会返回一个语言偏好对象的枚举,以客户端选择的语言偏好开始降序排列,这些偏好是客户端可以接受的(return an Enumeration of Locale objects indicating, in decreasing order starting with the preferred locale, the locales that are acceptable to the client)。
        如果客户端没有选择语言偏好,那getLocale方法返回的语言偏好就会为servlet container的默认偏好,而getLocales方法返回的枚举类型必须只包含一个元素,就是默认偏好。

 

 

SRV4.9 Request data encoding

        目前,很多浏览器发送字符不用content-type header限定编码,而把字符编码的决定权公开给HTTP request读取。如果没有被client request设定的话,Container用来创建request reader和解析POST数据的默认request编码是“ISO-8859-1”。如果client发送字符编码失败,getCharacterEncoding方法会返回null。
        如果client没有设定字符编码并且request数据被编码为与以上提及的默认编码不一致的编码,就会发生错误。为了解决这种情况,ServletRequest接口中加入了一个新的方法setCharacterEncoding(String enc)。开发者可以通过调用这个方法override container支持的字符编码。setCharacterEncoding方法会在从request中传送任何post数据和读取任何输入之前被调用。如果数据在方法调用前被读取,则不会对字符编码产生影响。

 

 

SRV4.10 Lifetime of the Request Object

        每个request对象都只在对应的servlet的service方法的范围内有效,或者在filter的doFilter方法的范围内有效。为了避免request对象创建的性能开销过大,container一般会回收request对象。开发者必须清楚的是,在以上描述的范围之外维护request对象的引用是不被推荐的,因为这有可能引起不可预知的结果。

你可能感兴趣的:(应用服务器,Web,servlet,浏览器,sun)