Bootstrap

Request 和 Response 详解

HTTP协议 之Request 和 Response 详解(servlet)

Request和Response的作用?

当我们打开浏览器,在地址栏中输入URL,然后我们就看到了网页。 原理是怎样的呢?

实际上我们输入URL后,我们的浏览器给Web服务器发送了一个Request, Web服务器接到Request后进行处理,生成相应的Response,然后发送给浏览器, 浏览器解析Response中的HTML,这样我们就看到了网页,过程如下图所示
这里写图片描述

我们的Request 有可能是经过了代理服务器,最后才到达Web服务器的。
过程如下图所示
这里写图片描述

代理服务器的主要功能有哪些?

代理服务器是介于浏览器和Web服务器之间的一台服务器。其功能是代理网络用户去取得网络信息。网络信息则是通过代理服务器进行中转的。更重要的是:Proxy Server(代理服务器)是Internet链路级网关所提供的一种重要安全功能,工作主要在开放系统互联(OSI)模型的对话层。

这里写图片描述

代理服务器能够让多台没有IP地址的电脑使用其代理功能高速、安全的访问互联网资源。当代理服务器客户端发出一个对外的资源访问请求,该请求被代理服务器识别并由代理服务器代为向外请求资源。

主要功能有

1.共享网络
如通过Squid、sygate、wingate、isa、ccproxy以及NT系统自带的网络共享等代理服务器访问外部站点的信息。这些代理服务器也都能提供企业级的文件缓存、复制和地址过来等服务。充分利用局域网出口的有限带宽,加快内网用户的访问速度,能解决仅仅有一条线路一个公有IP,在这种公有IP资源严重不足的情况下,满足局域网众多用户同时共享上网的需求。

2.访问代理
现在的网络环境中常常会出现网络拥挤或网络故障。用户通常都会通过代理服务器绕道访问目的站点;另外,代理服务器中通常会备份有相当数量的缓存文件,如果当前所访问的数据在代理服务器的缓存文件中,则可直接读取,而无需再连接到远端Web服务器。这样可以达到加快访问网站速度,节约通信带宽的目的。

3.提高速度
提高下载速度,突破一个IP、一个下载线程的限制以及电信和联通的用户互上对方的电影网站下载的限制。

4.突破限制
互联网上有许多开放的代理服务器,客户在访问权限受到限制时,而这些代理服务器的访问权限是不受限制的,刚好代理服务器在客户的访问范围之内,那么客户通过代理服务器访问目标网站就成为可能。通过代理服务器,国内高校使用教育网就能实现访问因特网,这就是高校内代理服务器流向的原因所在。

5.防止攻击
通过代理服务器完成内部主机的访问使主机地址等信息不会发送到外部,隐藏了自己的真实地址信息,还可隐藏自己的IP。更有效地保护了内部主机。

6.充当防火墙
360ARP防火墙在哪里
因为所有使用代理服务器的用户都必须通过代理服务器访问远程站点,因此在代理服务器上就可以设置相应的限制,以过滤或屏蔽某些信息。

7.方便对用户管理
通过代理服务器,管理员可以设置用户验证和记账功能,对用户进行登记,并对用户的访问时间、访问地点、信息浏览进行统计。没有登记的用户无权通过代理服务器访问Internet

8.隐藏身份
代理服务器使用内部用户访问Interner时受到保护,内部网的用户要对外发布信息就需要使用代理服务器的反向代理功能。这样就不会影响到内部网络的安全性能,起到隐藏身份的目的。

打开一个浏览器需要多次请求Request

  1. 当你在浏览器输入URL http://www.cnblogs.com 的时候,浏览器发送一个Request去获取 http://www.cnblogs.com 的html. 服务器把Response发送回给浏览器.

  2. 浏览器分析Response中的 HTML,发现其中引用了很多其他文件,比如图片,CSS文件,JS文件。

    [通过fiddler等抓包工具可以看到,请求资源文件往往是在访问html之后

  3. 浏览器会自动再次发送Request去获取图片,CSS文件,或者JS文件。

  4. 等所有的文件都下载成功后。 网页就被显示出来了。




Request和Responsed的消息结构


Request 的消息结构

先看Request 消息的结构, Request 消息分为3部分,
第一部分叫Request line,(请求行)
第二部分叫Request header, (请求头)
第三部分是body. (请求实体)
header和body之间有个空行, 结构如下图
这里写图片描述
第一行中的Method表示请求方法,比如”POST”,”GET”, Path-to-resoure表示请求的资源, Http/version-number 表示HTTP协议的版本号

当使用的是”GET” 方法的时候, body是为空的

Responsed 的消息结构

我们再看Response消息的结构, 和Request消息的结构基本一样。
同样也分为三部分,
第一部分叫Response line,
第二部分叫Response header,
第三部分是body. header和body之间也有个空行, 结构如下图
这里写图片描述
HTTP/version-number表示HTTP协议的版本号,
status-code为状态码,例如404 200等
message 相应的状态


ServletRequest 接口介绍及方法

定义:

   public interface ServletRequest

   定义一个Servlet引擎产生的对象,通过这个对象,Servlet可以获得客户端请求的数据。这个对象通过读取请求体的数据提供包括参数的名称、值和属性以及输入流的所有数据。

方法:

   1、getAttribute

   public Object getAttribute(String name);

   返回请求中指定属性的值,如果这个属性不存在,就返回一个空值。这个方法允许访问一些不提供给这个接口中其他方法的请求信息以及其他Servlet放置在这个请求对象内的数据。

   2、getAttributeNames

   public Enumeration getAttributeNames();

   返回包含在这个请求中的所有属性名的列表。

   3、getCharacterEncoding

   public String getCharacterEncoding();

   返回请求中输入内容的字符编码类型,如果没有定义字符编码类型就返回空值。

   4、getContentLength

   public int getContentLength();

   请求内容的长度,如果长度未知就返回-1。

   5、getContentType

   public String getContentType();

   返回请求数据体的MIME类型,如果类型未知返回空值。

   6、getInputStream

   public ServletInputStream getInputStream() throws IOException;

   返回一个输入流用来从请求体读取二进制数据。如果在此之前已经通过getReader方法获得了要读取的结果,这个方法会抛出一个IllegalStateException。

   7、getParameter

   public String getParameter(String name);

   以一个String返回指定的参数的值,如果这个参数不存在返回空值。例如,在一个HTTP Servlet中,这个方法会返回一个指定的查询语句产生的参数的值或一个被提交的表单中的参数值。如果一个参数名对应着几个参数值,这个方法只能返回通过getParameterValues方法返回的数组中的第一个值。因此,如果这个参数有(或者可能有)多个值,你只能使用getParameterValues方法。

   8、getParameterNames

   public Enumeration getParameterNames();

   返回所有参数名的String对象列表,如果没有输入参数,该方法返回一个空值。

   9、getParameterValues

   public String[] getParameterValues(String name);

   通过一个String对象的数组返回指定参数的值,如果这个参数不存在,该方法返回一个空值。

   10、getProtocol

   public String getProtocol();

   返回这个请求所用的协议,其形式是协议/主版本号.次版本号。例如对于一个HTTP1.0的请求,该方法返回HTTP/1.0。

   11、getReader

   public BufferedReader getReader() throws IOException;

   这个方法返回一个buffered reader用来读取请求体的实体,其编码方式依照请求数据的编码方式。如果这个请求的输入流已经被getInputStream调用获得,这个方法会抛出一个IllegalStateException。

   12、getRemoteAddr

   public String getRemoteAddr();

   返回发送请求者的IP地址。

   13、getRemoteHost

   public String getRemoteHost();

   返回发送请求者的主机名称。如果引擎不能或者选择不解析主机名(为了改善性能),这个方法会直接返回IP地址。

   14、getScheme

   public String getScheme();

   返回请求所使用的URL的模式。例如,对于一个HTTP请求,这个模式就是http。

   15、getServerName

   public String getServerName();

   返回接收请求的服务器的主机名。

   16、getServerPort

   public int getServerPort();

   返回接收请求的端口号。

   17、setAttribute

   public void setAttribute(String name, Object object);

   这个方法在请求中添加一个属性,这个属性可以被其他可以访问这个请求对象的对象(例如一个嵌套的Servlet)使用。

ServletResponse 接口介绍及方法

定义:

    public interface ServletResponse

   定义一个Servlet引擎产生的对象,通过这个对象,Servlet对客户端的请求作出响应。这个响应应该是一个MIME实体,可能是一个HTML页、图象数据或其他MIME的格式。

方法:

     1、getCharacterEncoding

   public String getCharacterEncoding();

   返回MIME实体的字符编码。这个字符编码可以是指定的类型,也可以是与请求头域所反映的客户端所能接受的字符编码最匹配的类型。在HTTP协议中,这个信息被通过Accept-Charset传送到Servlet引擎。

   有关字符编码和MIME的更多信息请参看RFC 2047。

   2、getOutputStream

   public ServletOutputStream getOutputStream() throws IOException;

   返回一个记录二进制的响应数据的输出流。

   如果这个响应对象已经调用getWriter,将会抛出IllegalStateException。

   3、getWriter

   public PrintWriter getWriter throws IOException;

   这个方法返回一个PringWriter对象用来记录格式化的响应实体。如果要反映使用的字符编码,必须修改响应的MIME类型。在调用这个方法之前,必须设定响应的content类型。

   如果没有提供这样的编码类型,会抛出一个UnsupportedEncodingException,如果这个响应对象已调用getOutputStream,会抛出一个getOutputStream。

   4、setContentLength

   public void setContentLength(int length);

   设置响应的内容的长度,这个方法会覆盖以前对内容长度的设定。

   为了保证成功地设定响应头的内容长度,在响应被提交到输出流之前必须调用这个方法。

   5、setContentType

   public void setContentType(String type);

   这个方法用来设定响应的content类型。这个类型以后可能会在另外的一些情况下被隐式地修改,这里所说的另外的情况可能当服务器发现有必要的情况下对MIME的字符设置。

   为了保证成功地设定响应头的content类型,在响应被提交到输出流之前必须调用这个方法。

HTTPServletRequest/Response 与 ServletRquest 接口的区别

servlet理论上可以处理多种形式的请求响应形式
http协议只是其中之一

所以HttpServletRequest、 HttpServletResponse分别是ServletRequest和ServletResponse的子类
HttpServletRequest和ServletRequest都是接口
HttpServletRequest继承自ServletRequest
HttpServletRequest比ServletRequest多了一些针对于Http协议的方法。

getHeader(String name),
getMethod() ,
getSession()
等等。
他们对应的实现类:
javax.servlet.ServletRequestWrapper (implements javax.servlet.ServletRequest)
javax.servlet.http.HttpServletRequestWrapper (implements javax.servlet.http.HttpServletRequest)

;