request对象封装了来自客户端的所有请求信息。在HTTP协议中,客户端发给服务端的所有信息都是通过request对象的请求头和请求体来传送的。

          SRV.4.1    HTTP协议参数

servlet的请求参数作为客户端请求的一部分都是以字符串形式传给servlet容器。当请求信息使用HttpServletRequest对象时,如果满足可用参数的必需条件,那么容器就会传送URI的查询参数和POST的表单数据。

参数以名值对方式存储,而且一个参数名可以对应多个参数值。ServletRequest接口的以下4个方法用于访问这些参数信息:

• getParameter
        • getParameterNames
        • getParameterValues
        • getParameterMap

getParameterValues方法查询一个参数名对应的所有参数值,然后以String数组返回。而getParameter方法与此类似,只不过getParameter只返回getParameterValues方法查询出来的String数组的第一个值而已。getParameterMap方法以Map方式返回所有的请求参数,当然,这个Map以参数名为key,参数值为对应的value。

从query字串和post提交的请求体获得的所有请求数据都会包装进请求参数集合中。query字串的数据优先性要高于post提交的数据。例如,客户端在地址栏的query参数有一个a=hello,而以post提交的请求体参数中有一个a=goodbye$a=world,那么最终服务端包装好的参数结果会排序为a=(hello,goodbye,world)。

作为GET请求的一部分的路径参数不会被当前API规范处理和显示。他们必须通过getRequestURI或者getPathInfo方法返回的String结果来解析。

          SRV.4.1.1    参数可用性

以下4点是使用post方式提交请求数据时必须满足的先决条件:

1. HTTP请求或者是HTTPS请求。

2. HTTP的请求方法为POST方式。

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

4. servlet已经在请求对象上初始化调用了getParameter方法。

若不满足上述条件,post提交的表单数据不会包含在参数集中,但post的数据本身仍然可以通过请求对象的输入流进行访问。若满足上述条件,post提交的表单数据就不能再通过请求对象的输入流进行直接访问了。

          SRV.4.2    属性

        Attributes是请求的关联对象,Attributes可以被容器用于标识Servlet API无法表达出来的信息,或者用于多个servlet之间相互沟通交流数据。Attributes可通过ServletRequest接口的下述方法进行访问:

• getAttribute
        • getAttributeNames
        • setAttribute

一个属性名只能对应一个属性值。以“java.”和“javax.”开头的属性名已经预留给Servlet规范本身。同样的,“sun.”和“com.sun”也已经预留给Sun微系统公司。建议所有的属性都是用倒置域名或Java的包命名规则来进行属性命名,这样可以确保属性名的唯一性。

          SRV.4.3    Headers

servlet通过HttpServletRequest接口的下述方法访问HTTP请求的头信息:

• getHeader
        • getHeaders
        • getHeaderNames

getHeader返回指定名字的header信息。一个头名可以对应多个头值,和request类似。若有多个值,getHeader只返回第一个请求头,而getHeaders则可以返回所有的头信息(以String对象的枚举返回)。

头包含了int和Date类型的字符串表示。通过HttpServletRequest的以下几个方法可以访问对应的请求头数据:

• getIntHeader
        • getDateHeader

如果getIntHeader方法不能把header转换为int类型,就会抛出NumberFormatException。同理,若getDateHeader方法不能正常转化Date类型,就会抛出IllegalArgumentExcetion。

          SRV.4.4    请求路径相关的元素

请求路径由多段重要信息组合而成。以下元素有请求的URI获得并由request对象展示:

1. Context Path:和ServletContext关联的路径前缀。如果应用的上下文是Web服务URL命名空间的默认上下文,那么Context Path就是空的。否则,它就以斜杠“/”开始以其他非斜杠字符结束。

2. Servlet Path:这段路径对应着处理请求的映射路径,它始于斜杠“/”。如果请求匹配于“/*”规则,那么这时的Servlet Path会是空字串。

3. PathInfo:这段既不是Context Path的一部分,也不是Servlet Path的一部分。它要么为空,要么就是以斜杠“/”作为前导字符的一段字符串。

HttpServletRequest接口的下述3个方法用于访问这些信息:

• getContextPath
        • getServletPath
        • getPathInfo

记住这么一点:除非请求的URI和路径部分的编码不同,否则以下等式永远成立:

requesetURI =  contextPath + servletPath + pathInfo。

为了理解这点,思考以下例子:

表1:上下文设置示例

Context Path

/catalog

Servet Manpping

Pattern: /lawn/*
Servlet: LawnServlet

Servlet Mapping

Pattern: /garden/*
Servlet: GardenServlet

Servet Mapping

Pattter: *.jsp
Servlet: JSPServlet

表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

          SRV.4.5    路径转换的方法

API里有两个便捷方法可以让开发人员获取Servlet对应的文件系统真实路径:

• ServletContext.getRealPath
        • HttpServletRequest.getPathTranslated

getRealPath方法接收一个String参数,然后返回这个参数对应的本地文件系统上的文件路径。getPathTranslated方法计算请求中的pathInfo对应的真实路径。

某些情况下Servlet容器无法获知这些方法对应的可用文件路径,例如当web应用是从压缩包中执行时、来自本地无法访问的远程文件系统时、或者数据库时,这些方法都会返回null。

          SRV.4.6    Cookies

HttpServletRequest接口提供了getCookies方法去获取请求对象的cookies数组,这些cookies是每次客户端发送请求时带到服务端的。典型情况下,发回客户端的cookies中仅有的信息就是cookie名值对。其他的cookie属性也可以在返回给浏览器时设置,例如注释之类的,当然通常是不会有这些数据的。

          SRV.4.7    SSL属性

如果发送的请求使用了HTTPS等安全协议,那调用ServletRequest接口的isSecure方法时,请求信息必须是安全的。web容器必须维护以下属性:

表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授权认证,那servlet容器必须展示给开发人员一个java.security.cert.X509Certificate对象数组,并且通过ServletRequest的javax.servlet.request.X509Certificate属性可访问这些授权。

这个数组以授信级联关系作为排序层次,授信链的第一级认证由客户端设置,下一级则为前一级认证做授权,以此类推。

          SRV.4.8    国际化

客户端可以指定web服务以哪种语言返回响应信息。这个语言设置由客户端的Accept-Language请求头指明。ServletRequest接口的下述方法用于侦测应答时需要的本地化设置:

• getLocale
        • getLocales

getLocale方法返回客户端更喜欢使用的locale。getLocales方法则返回一个Locale的枚举对象,依喜好级别依次列举客户端最想要的、可以接受的locale。

若客户端没有指定这些,getLocale方法就必须返回servlet容器的默认locale,而getLocales方法则必须返回包含默认locale的枚举对象。

          SRV.4.9    请求数据的编码

当下很多浏览器都并不指定编码格式,由服务程序自动决定读取请求数据时的编码方法。若客户端并未指定编码格式,那容器读取请求头和解析POST数据体时必须统一使用“ISO-8859-1”编码。但是,即使servlet容器默认都统一使用了“ISO-8859-1”,getCharacterEncoding方法也必须返回null,以明确告知开发人员此时客户端请求没有指定编码格式。

如果客户端未指定字符编码,而解析请求数据时又用了不同的编码规则,那就会出现乱码问题。为解决这种问题,ServletRequest接口新加了一个setCharacterEncoding(String enc)方法。开发人员通过它可以重设容器的编码方式。需要强调的是,这个方法必须在解析或读取任何请求数据和输入流之前被调用,否则不会生效。

          SRV.4.10    请求对象的生命周期

每个请求对象只在当前servlet的service方法域内可用,或者是在filter的doFilter方法域内可用。通常容器回收请求对象主要是为了避免创建新请求对象时的性能开销。开发人员必须避免在上述作用域外调用请求对象,否则极易导致不可预期的执行结果。

文档信息

Servlet 2.4 规范之第五篇:请求的更多相关文章

  1. Servlet 2.4 规范之第七篇:过滤器

    过滤器是一套java组件,用于在请求—>资源—>应答的这一过程中即时转换处理负载和头信息. 本章讲述了Servlet 2.4 API中一些类和方法,这些类和方法提供了一套轻量级框架用于过滤 ...

  2. Servlet 2.4 规范之第三篇:Servlet生命周期

        SRV.2.3    Servlet生命周期 servlet有着定义良好且明确的生命周期,它定义了servlet以怎样的方式加载和实例化.初始化.怎样处理客户端请求.以及怎样停止服务.生命周期 ...

  3. Servlet 2.4 规范之第六篇:响应

    响应对象封装了服务端返回给客户端的所有信息.在HTTP协议中,这些信息通过HTTP头和消息体传送. SRV.5.1    缓冲 出于效率考量,servlet容器可以缓冲输出数据,但这并非强制要求.常见 ...

  4. Servlet 2.4 规范之第四篇:Servlet上下文

    SRV.3.1    ServletContext接口说明 ServletContext接口定义了运行servlet的web应用中和servlet相关的视图信息.容器提供者负责提供ServletCon ...

  5. Servlet 2.4 规范之第一篇:概览

          写在前面的话: 本系列是对<Java Servlet Specification Version 2.4>的完全翻译,力争但不保证完美表达出英文原文的思想内涵.如有疏漏之处,还 ...

  6. Servlet 2.4 规范之第二篇:Servlet接口

    Servlet接口是Servlet API的最核心抽象类.所有的servlets都直接实现了这个接口,或者以更通用的方式继承了这个接口的实现类.Servlet API自带了两个实现了Servlet接口 ...

  7. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  8. Python之路【第十五篇】:Web框架

    Python之路[第十五篇]:Web框架   Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 1 2 3 4 5 6 ...

  9. 第五篇 :微信公众平台开发实战Java版之如何获取公众号的access_token以及缓存access_token

    一.access_token简介 为了使第三方开发者能够为用户提供更多更有价值的个性化服务,微信公众平台 开放了许多接口,包括自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等, 开 ...

随机推荐

  1. linux常用命令(配置查看,定时任务)

    1.查看所有待挂载设备信息 fdisk -l # fdisk -l Disk /dev/sda: bytes heads, sectors/track, cylinders, total sector ...

  2. selenium+phantomjs爬取京东商品信息

    selenium+phantomjs爬取京东商品信息 今天自己实战写了个爬取京东商品信息,和上一篇的思路一样,附上链接:https://www.cnblogs.com/cany/p/10897618. ...

  3. json.dumps ensure_ascii 方法

    在使用json.dumps时要注意一个问题   import json print (json.dumps('中国')) "\u4e2d\u56fd"   输出的会是 '中国' 中 ...

  4. re--读书笔记【转】

    原文链接 * 正则表达式入门 1.正则表达式的两种基本用途:搜索和替换. 2.正则表达式是一些用来匹配和处理文本的字符串. 小结:正则表达式是文本处理方面功能最强大的工具之一,正则表达式语言用来构造正 ...

  5. Mysql之查看数据库版本

    Mysql版本: 登入数据库的时候: select @@version; select version(); mysql> select @@version; +-----------+ | @ ...

  6. VMware-Ubuntu入门(1)

    大家都说Linux系统是让程序员用起来更有成就感的系统,我也来体验下: 对于小白鼠的我,并没有直接在电脑上重装Linux系统,而是通过VMware工具搭建Ubuntu虚拟linux环境. 首先展示下V ...

  7. [python subprocess学习篇] 调用系统命令

    http://www.jb51.net/article/57208.htm 3).Popen.communicate(input=None):与子进程进行交互.向stdin发送数据,或从stdout和 ...

  8. ansible /usr/bin/python: not found

    使用ansible命令的时候出错 ansible all -m ping 出现报错 192.168.199.154 | FAILED! => { "changed": fal ...

  9. 九度oj 题目1374:所有员工年龄排序

    题目描述: 公司现在要对所有员工的年龄进行排序,因为公司员工的人数非常多,所以要求排序算法的效率要非常高,你能写出这样的程序吗? 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为一 ...

  10. Use of @OneToMany or @ManyToMany targeting an unmapped class:hibernate映射错误

    hibernate映射异常:Use of @OneToMany or @ManyToMany targeting an unmapped class 新建了PO以后,要把PO所在的目录加入到Hiber ...