> 文档中心 > Servlet学习之HTTP协议

Servlet学习之HTTP协议

文章目录

  • 1.HTTP协议
    • 1.1 概念
    • 1.2 超文本
    • 1.3 W3C
    • 1.4 意义
  • 2.HTTP协议的内容
    • 2.1 请求协议
      • 2.1.1 请求协议的内容
      • 2.1.2 响应协议报文的分析
        • 请求行
        • 请求头
        • 空白行
        • 请求体
    • 2.2 响应协议
      • 2.2.1 响应协议的内容
      • 2.2.2 响应协议报文的分析
        • 状态行
        • 响应头
        • 空白行
        • 响应体
  • 2.3 GET与POST
      • 2.3.1 什么时候发送的是GET,什么时候发送的是POST?
      • 2.3.2 GET与POST的区别

1.HTTP协议

1.1 概念

超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,由W3C制定,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。

1.2 超文本

超文本是用超链接的方法,将各种不同空间的文字信息组织在一起的网状文本。超文本更是一种用户界面范式,用以显示文本及与文本之间相关的内容。更加简单的说,超文本是不同于普通文本的文本,例如:流媒体(声音、视频和图片)。

1.3 W3C

万维网(W3C)联盟创建于1994年,是Web技术领域最具权威和影响力的国际中立性技术标准机构。W3C已发布了200多项影响深远的Web技术标准及实施指南,如广为业界采用的超文本标记语言HTML(标准通用标记语言下的一个应用)、可扩展标记语言XML(标准通用标记语言下的一个子集)以及帮助残障人士有效获得Web信息的无障碍指南(WCAG)等,有效促进了Web技术的互相兼容,对互联网技术的发展和应用起到了基础性和根本性的支撑作用。

1.4 意义

规范了浏览器和服务器的数据交互(核心:键值对格式),对于B/S结构的开发来说,实现了B/S的解耦合,因为两者不必依赖与对方,只需要遵守HTTP协议即可。

耦合,从字面上来看有藕断丝连的意思,“耦” 这个字在中国汉语里指的是两个人在一起耕地,他俩各干各的互不影响,这也是“耦合”的由来。那么 低耦合也就是尽可能的使每个模块之间或者每个类之间再或者是每个方法之间的关联关系减少,这样可以使各自尽可能的独立,一个地方出错,不会影响全部,更能提高代码的重用性。

2.HTTP协议的内容

我们可以使用F12,然后找到network选项,当我们点击页面中的login按钮,我们的请求就会被发出,然后可以看到network中出现了一个新的选项我们点击该选项就可以查看相应协议的内容。

2.1 请求协议

接下来我们会用一段代码来展示HTTP的具体报文。

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>http协议</title></head><body><h1>get请求:</h1><form action="/servlet05/getServlet" method="get">    username<input type="text" name="username" /><br>    password<input type="password" name="userpwd" /><br>    <input type="submit" value="login"></form><h1>post请求:</h1><form action="/servlet05/postServlet" method="post">username<input type="text" name="username" /><br>    password<input type="password" name="userpwd" /><br>    <input type="submit" value="login"></form></body></html>

这段代码中,servlet05是WebAPP的名字,其中我们已经编写了GetServlet和PostServlet。这两个Servlet继承了GenericServlet并重写了其中的service方法。

其中的主要代码是:

//GetServletout.println("");   out.println("");     out.println("    "); out.println(" from get servlet");out.println("    ");out.println("    "); out.println(" 

from get servlet

"
); out.println(" ");out.println(""); //PostServletout.println(""); out.println(""); out.println(" "); out.println(" from post servlet");out.println(" "); out.println(" "); out.println("

from post servlet

"
); out.println(" "); out.println("");

并且已经在/webapp/WEB-INF/web.xml文件中添加了关联:

    <servlet> <servlet-name>getServlet</servlet-name> <servlet-class>com.bjpowernode.javaweb.servlet.GetServlet</servlet-class>    </servlet>    <servlet-mapping> <servlet-name>getServlet</servlet-name> <url-pattern>/getServlet</url-pattern>    </servlet-mapping>    <servlet> <servlet-name>pServlet</servlet-name> <servlet-class>com.bjpowernode.javaweb.servlet.PostServlet</servlet-class>    </servlet>    <servlet-mapping> <servlet-name>pServlet</servlet-name> <url-pattern>/postServlet</url-pattern>    </servlet-mapping>

2.1.1 请求协议的内容

HTTP请求(B -> S)协议的内容包括四部分:

  • 请求行
  • 请求头
  • 空白行
  • 请求体

HTTP请求协议的具体报文-Get:

GET /servlet05/getServlet?username=lucy&userpwd=1111 HTTP/1.1      请求行Host: localhost:8080     请求头Connection: keep-alivesec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"sec-ch-ua-mobile: ?0sec-ch-ua-platform: "Windows"Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Sec-Fetch-Site: same-originSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentReferer: http://localhost:8080/servlet05/index.htmlAccept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9    空白行请求体

HTTP请求协议的具体报文-Post:

POST /servlet05/postServlet HTTP/1.1 请求行Host: localhost:8080   请求头Connection: keep-aliveContent-Length: 25Cache-Control: max-age=0sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"sec-ch-ua-mobile: ?0sec-ch-ua-platform: "Windows"Upgrade-Insecure-Requests: 1Origin: http://localhost:8080Content-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Sec-Fetch-Site: same-originSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentReferer: http://localhost:8080/servlet05/index.htmlAccept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9  空白行username=lisi&userpwd=123     请求体

2.1.2 响应协议报文的分析

请求行

请求行包括三个部分:第一部分是请求方式(POST/GET…),第二部分是URI(/servlet05/postServlet),第三部分是请求协议版本号(HTTP/1.1 )

  • 请求方式一共有7种:

    • get(常用的)
    • post(常用的)
    • delete
    • put
    • head
    • options
    • trace
  • URI(统一资源标识符)

    • 什么是URI? 统一资源标识符。代表网络中某个资源的名字。但是通过URI是无法定位资源的。
    • 什么是URL?统一资源定位符。代表网络中某个资源,同时,通过URL是可以定位到该资源的。
    • URI和URL什么关系,有什么区别?
      • URL包括URI
      • http://localhost:8080/servlet05/index.html 这是URL。
      • /servlet05/index.html 这是URI。
  • HTTP协议版本号,具体可以参考https://network.51cto.com/article/679706.html

请求头

  • 请求的主机(localhost,这里我们是用本机做实验,所以ip地址是localhost)
  • 主机的端口(8080)
  • 浏览器信息
  • 平台信息
  • cookie等信息

空白行

空白行是用来区分“请求头”和“请求体”。

请求体

向服务器发送的具体数据。比如我们form表格中的信息(username=lisi&userpwd=123 )。如果是使用get请求那么这一行是空的。

2.2 响应协议

同样的,我们仍可以使用F12,然后找到network选项,当我们点击页面中的login按钮,我们的请求就会被发出,然后可以看到network中出现了一个新的选项我们点击该选项就可以查看相应协议的内容。

2.2.1 响应协议的内容

HTTP响应(S -> B)协议的内容包括四部分:

  • 状态行
  • 响应头
  • 空白行
  • 响应体

HTTP响应协议的具体报文:

HTTP/1.1 200 ok  状态行Content-Type: text/html;charset=UTF-8 响应头Content-Length: 160Date: Mon, 08 Nov 2021 13:19:32 GMTKeep-Alive: timeout=20Connection: keep-alive   空白行  响应体     from get servlet         

from get servlet

2.2.2 响应协议报文的分析

状态行

状态行包括3个部分。第一部分是关于HTTP协议的版本号(HTTP/1.1),第二部分是状态码(200),第三部分是状态的描述信息(ok)。

  • 关于协议版本号具体可参考:https://network.51cto.com/article/679706.html

  • 常见的状态码有200(访问正常结束)、404(访问资源失败,这个时候要么是路径写错了,要么是服务器未启动成功)、405(前端发送的请求与后端处理的请求方式不一致导致的,比如说前端发送get请求,而后端使用post处理)、500(当服务器的程序出错会出现该状态码)。一般来说,4开头我们认为是浏览器的错误导致的,5开头的状态码是由于服务器的错误导致的

  • 状态描述信息:ok(访问正常结束)not found(资源找不到)

响应头

  • 响应的内容类型:text/html;charset=UTF-8
  • 响应的内容长度:160
  • 响应的时间

空白行

空白行就是用来分割响应头和响应体的。

响应体

响应体就是响应的正文,这些内容是一个长的字符串,这个字符串被浏览器渲染,解释并执行,最终展示出效果。

2.3 GET与POST

2.3.1 什么时候发送的是GET,什么时候发送的是POST?

到目前为止,只有一种情况可以发送POST请求:使用form表单,并且form标签中的method属性值为:method=“post”。

其他所有情况一律都是get请求:

  • 在浏览器地址栏上直接输入URL,敲回车,属于get请求。
  • 在浏览器上直接点击超链接,属于get请求。
  • 使用form表单提交数据时,form标签中没有写method属性,默认就是get
  • 或者使用form的时候,form标签中method属性值为:method=“get”

2.3.2 GET与POST的区别

地址栏可见

  • get请求发送数据的时候,数据会挂在URI的后面,并且在URI后面添加一个“?”,"?"后面是数据。这样会导致发送的数据回显在浏览器的地址栏上。(get请求在“请求行”上发送数据)
    • http://localhost:8080/servlet05/getServlet?username=zhangsan&userpwd=1111
  • post请求发送数据的时候,在请求体当中发送。不会回显到浏览器的地址栏上。也就是说post发送的数据,在浏览器地址栏上看不到。(post在“请求体”当中发送数据)

类型及长度限制

  • get请求只能发送普通的字符串。并且发送的字符串长度有限制,不同的浏览器限制不同。这个没有明确的规范。
  • get请求无法发送大数据量。
  • post请求可以发送任何类型的数据,包括普通字符串,流媒体等信息:视频、声音、图片。
  • post请求可以发送大数据量,理论上没有长度限制。

适用条件

  • get请求在W3C中是这样说的:get请求比较适合从服务器端获取数据。
  • post请求在W3C中是这样说的:post请求比较适合向服务器端传送数据。

安全性

  • get请求是安全的。get请求是绝对安全的。为什么?因为get请求只是为了从服务器上获取数据。不会对服务器造成威胁。
  • post请求是危险的。为什么?因为post请求是向服务器提交数据,如果这些数据通过后门的方式进入到服务器当中,服务器是很危险的。另外post是为了提交数据,所以一般情况下拦截请求的时候,大部分会选择拦截(监听)post请求。

缓存

  • get请求支持缓存。

    • 如果我们不希望get请求走缓存,怎么办?怎么避免走缓存?我希望每一次这个get请求都去服务器上找资源,我不想从本地浏览器的缓存中取。
      • 只要每一次get请求的请求路径不同即可。
      • https://n.sinaimg.cn/finance/590/w240h350/20211101/7cabc342ff5b9dc018b4b00cc.jpg?t=789789787897898
      • https://n.sinaimg.cn/finance/590/w240h350/20211101/7cabc342ff5b9dc018b4b00cc.jpg?t=789789787897899
      • https://n.sinaimg.cn/finance/590/w240h350/20211101/7cabc342ff5b9dc018b4b00cc.jpg?t=系统毫秒数
      • 怎么解决?可以在路径的后面添加一个每时每刻都在变化的“时间戳”,这样,每一次的请求路径都不一样,浏览器就不走缓存了。
  • post请求不支持缓存。(POST是用来修改服务器端的资源的。)

    • post请求之后,服务器“响应的结果”不会被浏览器缓存起来。因为这个缓存没有意义。