Servlet规范之The Request
创始人
2024-04-11 04:59:30
0

The Request

文章是对 JSR-000340 JavaTM Servlet 3.1 Final Release的Java™ Servlet规范的翻译,尚未校准

文章目录

  • The Request
    • HTTP协议参数
      • When Parameters Are Available
    • 文件上传
    • Attributes
    • Headers
    • Request Path 元素
    • 路径转换方法
    • Non Blocking IO
    • Cookies
    • SSL Attributes
    • 国际化
    • 请求数据的编码
    • 请求对象的生命周期


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

HTTP协议参数

Servlet的请求参数是由客户端发送至Servlet容器的字符串,作为其请求的一部分。当请求是一个HttpServletRequest对象,并且符合第24页 "When Parameters Are Available"中规定的条件时,容器会从URI查询字符串和POST-ed数据中填充参数。

参数被存储为一组name-value对。对于任何给定的参数名称,可以存在多个参数值。ServletRequest接口的下列方法可用于访问参数。

  • getParameter
  • getParameterNames
  • getParameterValues
  • getParameterMap

getParameterValues方法返回一个字符串对象数组,其中包含与参数名称相关的所有参数值。从getParameter方法返回的值必须是getParameterValues返回的String对象阵列中的第一个值。getParameterMap方法返回请求的参数的java.util.Map,它包含作为键的名称和作为映射值的参数值。

来自查询字符串和帖子正文的数据被汇总到请求参数集。查询字符串的数据会在帖子正文的数据之前呈现。例如,如果一个请求的查询字符串为a=hello,帖子正文为a=goodbye&a=world,那么产生的参数集将被排序为a=(hello, goodbye, world)

作为GET请求的一部分的路径参数(如HTTP 1.1所定义的)不被这些API所公开。它们必须从getRequestURI方法或getPathInfo方法返回的String值中解析出来。

When Parameters Are Available

以下是必须满足的条件,然后才会将表单数据填充到参数集中。

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

如果不满足这些条件,并且post form数据不包括在参数集中,那么post数据仍然必须通过请求对象的输入流提供给servlet。如果条件得到满足,POST数据将不再可用于直接从请求对象的输入流中读取。

文件上传

Servlet容器允许在数据以multipart/form-data形式发送时上传文件。

如果满足以下任何一个条件,Servlet容器就会提供multipart/form-data处理。

  • 处理请求的servlet被注释为@MultipartConfig,定义在第8-70页的第8.1.5节"@MultipartConfig"。
  • 部署描述符包含处理请求的Servlet的multipart-config元素。

如何提供multipart/form-data类型的请求中的数据,取决于servlet容器是否提供multipart/form-data处理:

  • 如果servlet容器提供了multipart/form-data处理,数据将通过HttpServletRequest中的下列方法提供:

    • public Collection getParts()
    • public Part getPart(String name)

    每个part都可通过Part.getInputStream方法访问头部,相关的内容类型和内容。

    对于以表单数据的Content-Disposition的部分,即使没有文件名,该部分的字符串值也将通过HttpServletRequest上的getParametergetParameterValues方法得到该部分的名称。

  • 如果servlet容器不提供 multi-part/form-data处理,数据将通过HttpServletReuqest.getInputStream来获得。

Attributes

属性是与一个请求相关的对象。属性可以由容器设置,以表达无法通过API表达的信息,也可以由Servlet设置,以向另一个Servlet传递信息(通过RequestDispatcher)。属性可以通过ServletRequest接口的下列方法来访问:

  • getAttribute
  • getAttributeNames
  • setAttribute

一个属性名称只能关联一个属性值。

java. javax.开头的属性名被保留给本规范定义。同样,以sun.com.sun.oraclecom.oracle开头的属性名也被保留给Oracle公司定义。建议放在属性集中的所有属性都按照《Java编程语言规范》建议的反向域名惯例来命名包。

Headers

一个servlet可以通过HttpServletRequest接口的以下方法访问HTTP请求的头信息:

  • getHeader
  • getHeaders
  • getHeaderNames

getHeader方法返回一个给定的头的名称。在一个HTTP请求中可以有多个同名的头,例如Cache-Control头。如果有多个同名的头信息,getHeader方法会返回请求中的第一个头信息。getHeaders方法允许访问所有与特定头名称相关的头值,返回一个Enumeration的字符串对象。

头信息可以包含 intDate数据的String表示。HttpServletRequest接口的下列方便方法提供了对这些格式之一的头数据的访问:

  • getIntHeader
  • getDateHeader

如果getIntHeader方法不能将头的值翻译成int,就会抛出NumberFormatException。如果getDateHeader方法不能将标题翻译成Date对象,就会抛出IllegalArgumentException

Request Path 元素

服务请求的servlet的请求路径由许多重要部分组成。以下元素从请求URI路径中获得,并通过请求对象暴露:

  • Context Path: 与ServletContext相关的路径前缀,该Servlet是其中的一部分。如果这个上下文是基于Web服务器的URL名称空间的 "default"上下文,这个路径将是一个空字符串。否则,如果该上下文没有基于服务器名称空间的根目录,那么该路径以一个/字符开始,但不以一个/字符结束。
  • Servlet Path: 直接对应于激活该请求的映射的路径部分。这个路径以/字符开始,除非请求与/*或" "模式匹配,在这种情况下,它是一个空字符串。
  • PathInfo: 请求路径中不属于Context Path或Servlet Path的部分。如果没有额外的路径,它就是空的,或者是一个带/的字符串。

使用HttpServletRequest接口中的下面方法来访问这些信息:

  • getContextPath
  • getServletPath
  • getPathInfo

需要注意的是,除了请求URI和路径部分的URL编码不同,下面的等式总是正确的:

requestURI = contextPath + servletPath + pathInfo

举几个例子来说明上述观点,请考虑以下几点:

TABLE 3-1 Example Context Set Up

ContextPath/catalog
ServletMappingPattern: /lawn/*
Servlet: LawnServlet
ServletMappingPattern: /garden/*
Servlet: GardenServlet
ServletMappingPattern: *.jsp
Servlet: JSPServlet

The following behavior is observed:

TABLE 3-2 Observed Path Element Behavior

Request PathPath Elements
/catalog/lawn/index.htmlContextPath: /catalog
ServletPath: /lawn
PathInfo: /index.html
/catalog/garden/implements/ContextPath: /catalog
ServletPath: /garden
PathInfo: /implements/
/catalog/help/feedback.jspContextPath: /catalog
ServletPath: /help/feedback.jsp
PathInfo: null

路径转换方法

在API中有两个方便的方法,允许开发者获得相当于特定路径的文件系统路径。这些方法是:

  • ServletContext.getRealPath
  • HttpServletRequest.getPathTranslated

getRealPath方法接受一个String参数,并返回一个路径所对应的本地文件系统中的文件的String表示。getPathTranslated方法计算请求的pathInfo的真实路径。

在Servlet容器无法为这些方法确定有效的文件路径的情况下,例如,当Web应用程序从归档文件、在本地无法访问的远程文件系统或在数据库中执行时,这些方法必须返回空。JAR文件的META-INF/resources目录下的资源,只有在调用getRealPath()时,容器已经将其从包含的JAR文件中解压,才必须考虑,在这种情况下,必须返回解压的位置。

Non Blocking IO

Web容器中的非阻塞请求处理有助于改善不断增长的对改进Web容器可扩展性的需求,增加Web容器可同时处理的连接数。Servlet容器中的非阻塞IO允许开发者在数据可用时读取数据,或在可能时写入数据。非阻塞IO只适用于Servlet和过滤器中的异步请求处理(如第2-10页第2.3.3.3节 "异步处理 "中的定义),以及升级处理(如第2-20页第2.3.3.5节 "升级处理 "中的定义)。否则,当调用ServletInputStream.setReadListenerServletOutputStream.setWriteListener时,必须抛出一个IllegalStateException

The ReadListener provides the following callback methods for non blocking IO

ReadListener为非阻塞性IO提供以下回调方法:

  • ReadListener
    • onDataAvailable(). 当可以从传入的请求流中读取数据时,onDataAvailable方法会被调用到 ReadListener上。容器将在数据可被读取时第一次调用该方法。容器随后将调用onDataAvailable方法,当且仅当ServletInputStream上的isReady方法(如下所述)返回false
    • onAllDataRead(). 当你完成了对注册了监听器的ServletRequest的所有数据的读取时,onAllDataRead方法被调用。
    • onError(Throwable t). 如果在处理请求时有任何错误或异常,onError方法会被调用。

Servlet容器必须以线程安全的方式访问ReadListener中的方法。

除了上面定义的 ReadListener之外,在ServletInputStream类中还增加了以下方法:

  • ServletInputStream
    • boolean isFinished(). 当所有与 ServletInputStream相关的请求数据被读取时,isFinished方法返回true。否则它将返回false
    • boolean isReady(). isReady方法返回true,如果数据可以无阻塞地被读取。如果没有数据可以在不阻塞的情况下被读取,则返回 “false”。如果isReady返回false,调用read方法是非法的,必须抛出一个IllegalStateException
    • void setReadListener(ReadListener listener). 设置上面定义的ReadListener,使其被调用,以非阻塞的方式读取数据。一旦监听器与给定的ServletInputStream相关联,容器就会在数据可以读取、所有数据都已读取或处理请求时出现错误时调用ReadListener的方法。注册一个ReadListener将启动非阻塞的IO。此时切换到传统的阻塞式IO是非法的,必须抛出一个IllegalStateException。在当前请求的范围内对setReadListener的后续调用是非法的,必须抛出IllegalStateException

Cookies

HttpServletRequest接口提供了getCookies方法来获取请求中存在的cookies数组。这些cookie是在客户端发出的每个请求中从客户端发送到服务器的数据。通常情况下,客户端作为cookie的一部分发回的唯一信息是cookie名称和cookie值。当cookie被发送到浏览器时可以设置的其他cookie属性,如评论,通常不被返回。该规范还允许cookies为HttpOnlycookies。HttpOnlycookie向客户端表明,它们不应该被暴露给客户端脚本代码(除非客户端知道要寻找这个属性,否则它不会被过滤掉)。使用HttpOnly cookies有助于减轻某些类型的跨站脚本攻击。

SSL Attributes

如果一个请求是通过安全协议(如HTTPS)传输的,这一信息必须通过ServletRequest接口的isSecure方法公开。Web容器必须向Servlet程序员公开以下属性:

TABLE 3-3 Protocol Attributes

AttributeAttribute NameJava Type
cipher suitejavax.servlet.request.cipher_suiteString
bit size of the algorithmjavax.servlet.request.key_sizeInteger
SSL session idjavax.servlet.request.ssl_session_idString

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

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

国际化

客户端可以选择向网络服务器表明他们希望响应的语言。这个信息可以从客户端使用Accept-Language标头和HTTP/1.1规范中描述的其他机制来传达。ServletRequest接口中提供了以下方法来确定发送者的首选语言。

  • getLocale
  • getLocales

getLocale方法将返回客户想要接受的内容的首选地区。参见RFC 2616 (HTTP/1.1)第14.4节,了解更多关于如何解释Accept-Language头以确定客户端的首选语言。

getLocales方法将返回一个Locale对象的枚举,按照从首选语言开始的递减顺序,指出客户可以接受的语言。

如果客户没有指定首选的locale,getLocale方法返回的locale必须是servlet容器的默认locale,getLocales方法必须包含默认locale的一个Locale元素的枚举。

请求数据的编码

目前,许多浏览器并不随Content-Type头发送 char编码修饰符,这就使读取HTTP请求的字符编码的确定成为可能。如果客户端请求没有指定编码,容器用来创建请求阅读器和解析POST数据的默认编码必须是 “ISO-8859-1”。然而,为了向开发者表明,在这种情况下,客户端未能发送字符编码,容器会从getCharacterEncoding方法中返回null

如果客户端没有设置字符编码,而请求数据的编码与上述的默认编码不同,就会发生中断。为了补救这种情况,一个新的方法setCharacterEncoding(String enc)已经被添加到ServletRequest接口中。开发者可以通过调用这个方法来覆盖由容器提供的字符编码。它必须在解析任何职位数据或从请求中读取任何输入之前被调用。一旦数据被读取,调用此方法将不会影响编码。

请求对象的生命周期

每个请求对象只在servlet的service方法的范围内有效,或者在过滤器的doFilter方法的范围内有效,除非组件的异步处理被启用,并且startAsync方法被调用到请求对象上。在异步处理发生的情况下,请求对象仍然有效,直到completeAsyncContext上被调用。容器通常会回收请求对象,以避免创建请求对象的性能开销。开发者必须意识到,不建议在上述范围之外维护对startAsync未被调用的请求对象的引用,因为这可能会产生不确定的结果。

在升级的情况下,上述情况仍然适用。

相关内容

热门资讯

深圳个人破产法规很及时 在深圳... 深圳创业园深圳找合伙人一起创业创业项目排行榜前十名天津创业适合做什么没人注意的暴利行业一年赚一百万很...
深圳创业密度连续7年居全国大中... 深圳创业园深圳找合伙人一起创业创业项目排行榜前十名天津创业适合做什么没人注意的暴利行业一年赚一百万很...
返乡创业,双手托起致富梦 20... 农村创业50个项目返乡创业无息贷款适合农村开的十五种店没人注意的暴利行业农民工返乡创业有哪些项目20...
面向对象设计模式:结构型模式之... 一、引入 访问 FB:代理服务器 二、代理模式 aka Surrogate 2....
适大学生创业项目合大学生创业项... 创业项目有哪些项目创业项目大全00后无资金如何创业创业基础项目2021必火的创业项目加盟大学生创新创...
富国创业板指数分级 富国创业板... 富国指数基金富国创业板基金161022161022基金公告创业板指数今日多少富国中证军工指数分级基金...
大学生创意创业好项目 大学生创... 创业项目有哪些项目创业项目大全00后无资金如何创业创业基础项目2021必火的创业项目加盟大学生创新创...
Spark Join Spark Join关联形式内关联外关联左外关联右外关联全外关联左半/逆关联关联机制NLJSMJHJ...
Aptos发布模块 背景 之前那么文章我们已经了解了如何使用Aptos提供的TypeScript SDK在Aptos实现...
挑战杯创业计划大赛 挑战杯创业... 挑战杯获奖论文挑战杯创新创业大赛挑战杯项目是什么挑战杯历届时间创青春创业计划大赛需要有产品吗挑战杯创...
“挑战杯”大学生创业计划大赛 ... 挑战杯获奖论文挑战杯创新创业大赛挑战杯项目是什么挑战杯历届时间创青春创业计划大赛需要有产品吗挑战杯创...
《面向对象程序设计》授课计划2... 面向对象程序设计授课计划可参照此计划,在课前预习。(待完善)...
挑战杯的含金量到底有多大? 挑... 挑战杯获奖论文挑战杯创新创业大赛挑战杯项目是什么挑战杯历届时间创青春创业计划大赛需要有产品吗挑战杯创...
【深度学习】预训练语言模型-B... 1.BERT简介         BERT是一种预训练语言模型(pre-traine...
禾观科技一面经历 文章目录 redis 的热key问题,某台redis节点负载高如何解决?那么在日常开发中,如何识别到...
有什么自主创业自主创业项目项目... 有什么自己创业的小项目2021创业项目排行榜加盟创业商机网2021必火的创业项目加盟最挣钱没人干的行...
【Python】如何使用 Py... Playwright 是一种流行的用于测试 Web 应用程序的自动化工具,它提供了多种...
2020自主创业有些好项目 2... 有什么自己创业的小项目2021创业项目排行榜加盟创业商机网2021必火的创业项目加盟最挣钱没人干的行...
创业项目计划书范文 创业项目计... 项目计划书模板范文创意项目计划书创业商业计划书模板范文企业计划书怎么写范例创新创业项目计划书范文案例...
clash常见开发者问题——内... 1.无法解析host文件内的内容 进入服务器配置文件的编辑  由于dns被clash接管了...