Servlet(中)

29 阅读12分钟

一、HTTP协议

1. 常见的请求和响应信息

HTTP请求头:

image-20240121224505376

image-20240121224537687

HTTP响应头:

image-20240121224609053

image-20240121224855124

2. HTTP响应状态码

当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。HTTP状态码的英文为HTTP Status Code

常见的响应状态码:

  • 200 - 请求成功
  • 301 - 资源(网页等)被永久转移到其它URL
  • 404 - 请求的资源(网页等)不存在
  • 500 - 内部服务器错误

HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用

HTTP 状态码共分为5种类型:

分类分类描述
1xx信息,服务器收到请求,需要请求者继续执行操作
2xx成功,操作被成功接收并处理
3xx重定向,需要进一步的操作以完成请求
4xx客户端错误,请求包含语法错误或无法完成请求
5xx服务器错误,服务器在处理请求的过程中出现了错误

生动形象:

img转存失败,建议直接上传图片文件

img转存失败,建议直接上传图片文件

1) 100类状态码

属于信息型状态码,表达服务器正在处理请求

  • 100状态码:表示客户端应继续其请求
  • 101状态码:表示切换协议。服务器根据客户端的请求切换协议,只能切换到更高级的协议
  • 102状态码:表示由WebDAV(RFC 2518)扩展的状态码,意思是处理将被继续执行

2) 200类状态码

成功状态码,表达请求已经正常处理完毕

  • 200状态码:表示请求成功完成,请求的的响应头或数据响应正常返回。这也是网站网页应当正常表现的一个状态码。201状态码:表示成功请求并创建了新的资源
  • 202状态码:表示已经接受请求,但未处理完成
  • 203状态码:表示非授权信息,请求成功。但返回的meta信息不在原始的服务器,而是一个副本
  • 204状态码:表示服务器成功处理了请求,但不需要返回任何实体内容,并且希望返回更新了的元信息
  • 205状态码:表示服务器成功处理了请求,且没有返回任何内容
  • 206状态码:表示服务器已经成功处理了部分 GET 请求
  • 207状态码:表示由WebDAV(RFC 2518)扩展的状态码,代表之后的消息体将是一个XML消息,并且可能依照之前子请求数量的不同,包含一系列独立的响应代码

3) 300类状态码

重定向状态码,需要进行额外操作以完成请求

  • 300状态码:多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端
  • (常用)301状态码:表示请求的网页已永久移动到新位置
  • (常用:也叫做重定向)302状态码:表示临时性重定向
  • 303状态码:表示临时性重定向,且总是使用 GET 请求新的 URI
  • 304状态码:表示自从上次请求后,请求的网页未修改过
  • 305状态码:表示表示所请求的资源必须通过代理访问
  • 306状态码:表示已经被废弃的HTTP状态码
  • 307状态码:表示临时重定向,与302类似,使用GET请求重定向

4) 400类状态码

客户端错误状态码,导致服务器无法处理请求

  • 401状态码:表示访问错误、被拒绝
  • 403状态码:表示禁止访问:IIS 定义了许多不同的403错误
  • 404状态码:表示未找到,表示没有找到文件或目录
  • 405状态码:表示用来访问本页面的HTTP谓词不被允许(方法不被允许)
  • 406状态码:表示客户端浏览器不接受所请求页面的 MIME 类型
  • 407状态码:表示要求进行代理身份验证
  • 412状态码:表示前提条件失败
  • 413状态码:表示请求实体太大
  • 414状态码:表示请求 URI 太长
  • 415状态码:表示不支持的媒体类型
  • 416状态码:表示所请求的范围无法满足
  • 417状态码:表示执行失败
  • 423状态码:表示锁定的错误
  • 424状态码:表示由于之前的某个请求发生的错误,导致当前请求失败
  • 425状态码:表示服务器不愿意冒风险来处理该请求,原因是处理该请求可能会被“重放”,从而造成潜在的重放攻击
  • 426状态码:表示客户端应当切换到TLS/1.0
  • 449状态码:表示由微软扩展,代表请求应当在执行完适当的操作后进行重试
  • 451状态码:表示该请求因法律原因不可用

5) 500类状态码

服务器错误状态码,服务器原因导致处理请求出错

  • 500状态码:内部服务器错误
  • 501状态码:表示页眉值指定了未实现的配置,在参数中有语法错误
  • 502状态码:表示Web 服务器用作网关或代理服务器时收到了无效响应
  • 503状态码:表示服务不可用,错误的命令序列
  • 504状态码:表示网关超时,未执行该参数的命令
  • 505状态码:表示HTTP 版本不受支持
  • 506状态码:表示服务器存在内部配置错误:被请求的协商变元资源被配置为在透明内容协商中使用自己
  • 507状态码:表示服务器无法存储完成请求所必须的内容。这个状况被认为是临时的。WebDAV (RFC 4918)
  • 509状态码:表示服务器达到带宽限制。这不是一个官方的状态码,但是仍被广泛使用
  • 510状态码:表示获取资源所需要的策略并没有被满足
  • 530状态码:表示未登录
  • 532状态码:表示存储文件需要帐户
  • 550状态码:表示未执行请求的操作。文件不可用(例如,未找到文件,没有访问权限)
  • 551状态码:表示请求的操作异常终止:未知的页面类型
  • 552状态码:表示请求的文件操作异常终止:超出存储分配(对于当前目录或数据集)
  • 553状态码:表示未执行请求的操作。不允许的文件名

3. 什么是HTTP协议

超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用广泛的一种网络协议。是工作在TCP/IP协议基础上的,所有的WWW文件都遵守这个标准

HTTP是TCP/IP协议的一个应用层协议,HTTP也是我们Web开发的基础

HTTP1.0是短连接,HTTP1.1是长连接,连接会不会马上断掉

HTTP/1.0与HTTP/1.1的区别

  • 支持的请求方法不同,HTTP1.0不支持OPTIONS、TRACE、CONNECT三种请求方式,HTTP1.1不支持LINK和UNLINK两种请求方式。其中,CONNECT(隧道协议)方式用来进行SSL\TLS加密通讯,所以HTTP1.0自然也不支持HTTPS
  • HTTP1.0没有host请求头,意味着HTTP1.0不支持在一台HTTP服务器上搭建多个web站点。比如,你不能同时在一台服务器上托管www.baidu.com和www.taobao.com两个域名。而HTTP1.1协议里host一定要传
  • HTTP1.0默认都是非持久连接,一次HTTP请求完成后就会断开;HTTP1.1默认都是持久连接,一次连接后可以持续发送请求,直到一方断开连接
  • HTTP1.1支持长链接,自然地会发展出管线化技术(pipeline),HTTP1.0只有部分服务器通过非标准手段实现了长链接,所以不一定支持管线化
  • HTTP/1.1加入了一个新的状态码100(Continue)
  • HTTP/1.1加入了一些cache的新特性,当缓存对象的Age超过Expire时变为stale对象,cache不需要直接抛弃stale对象,而是与源服务器进行重新激活(revalidation)
  • HTTP/1.1引入了Chunked transfer-coding来将消息分割成若干个任意大小的数据块,避免缓冲整个消息带来的过载
  • HTTP1.1主要是在1.0的基础上优化性能,以及通过扩展http header的方式增加了部分功能。1.1相当于1.0的特性增强版

4. HTML请求分析

当访问test.html页面时, 问浏览器发出几次HTTP请求?

一个资源会发送一次请求,比如test.html中包含多个图片,每张图片也都请求一次

可以在浏览器调用调试模式去抓包

5. HTTP请求包分析(GET)

HTTP请求包包含下面两个部分:请求行、请求头

image-20240122121009164

创建表单:

<!DOCTYPE html>
<html lang="en">
	韩顺平 Java 工程师
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
    <h1>用户登录</h1>
    <form action="http://localhost:8080/http/login" method="get">
    u: <input type="text" name="username"/><br/>
    p: <input type="password" name="pwd"/><br/>
    <input type="submit" value="用户登录"> <input type="reset" value="清空">
    </form>
</body>
</html>

写Servlet:

package com.servlet.http;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //为了让浏览器显示中文,需要告诉浏览器,编码是utf-8
        //text/html是MIME,告诉浏览器,返回的数据是html格式的数据
        //设置编码必须要在response.getWriter之前
        response.setContentType("text/html;charset=utf-8");
        //通过response获取流PrintWriter,可以给浏览器回复数据
        PrintWriter writer = response.getWriter();
        writer.print("<h1>登录成功~</h1>");
        //flush和close不写也可以,写上为了保险
        writer.flush();
        writer.close();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
}

抓包看到,有数据的情况会看到在GET中就包含了这些参数和值

image-20240122121141458

6. HTTP请求包分析(POST)

修改login.html,将提交方式改成post

同样的抓包,看一下POST的参数和参数值

image-20240122124328948

image-20240122124825687

%E9%9F%A9%E9%A1%BA%E5%B9%B3是url编码 , 在服务端会自动解码,测试工具:tool.chinaz.com/tools/urlen…

7. GET请求POST请求分别有哪些?

Get请求:

  1. form标签 method=get
  2. a标签
  3. link标签引入css(以get方式来获取资源)
  4. Script标签引入js文件(以get方式来获取资源)
  5. img标签引入图片(以get请求来获取图片)
  6. iframe引入html页面
  7. 在浏览器地址栏中输入地址后敲回车(用的比较多)

Post请求:

  1. form标签 method=post

8.HTTP响应包分析

包含三个部分:响应行、响应头、响应体

image-20240122183213699

9. 302状态码

就是重定向,当前server或网页临时移动了,需要重新请求另一个地址

演示如下功能:

  1. 浏览器请求T1Servelt
  2. T1Servlet返回302的状态码, 并且指定浏览器重定向到hi.html
  3. 浏览器发出第二次请求hi.html

添加T1Servlet和映射:

<servlet>
    <servlet-name>t1Servlet</servlet-name>
    <servlet-class>com.olivier.servlet.T1Servlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>t1Servlet</servlet-name>
    <url-pattern>/t1</url-pattern>
</servlet-mapping>

写一个hi.html,随便写一个

Servlet如下:

public class T1Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //一个请求来了,就重定向到hi.html
        //这样就会返回302状态码,响应头Location:static/hi.html
        resp.sendRedirect("static/hi.html");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

测试会发现响应头如下,确实如上面所说:

image-20240122190006395

10. 304状态码

当选中禁用缓存的时候,可以看到请求资源的响应头会包含一个参数叫做Last-modified

image-20240122190911459

当我们请求资源的时,服务器会返回该资源的最近修改时间Last-modified

如果浏览器禁用缓存, 这个Last-Modified:信息就没有使用, 浏览器就每次要求返回该资源,因为每次都返回最新的资源,所以这个时间在请求头里没有用到

image-20240122191301383

当把禁用缓存去掉的时候

image-20240122190623981

我们会发现请求头出现了一个新的参数If-Modified-Since

image-20240122191424499

如果浏览器没有禁用缓存,浏览器在请求时,就会If-Modified-Since,含义:①告诉服务器我有该资源;②该资源的最近修改时间是Sun, 21 Jan 2024 02:59:48 GMT,这时服务器就会比较时间,如果服务器的资源更新过, 就会返回该资源 , 如果发现没有修改,就返回

不修改页面直接请求,会发现304

image-20240122191743433

如果修改资源再请求,会发现200

image-20240122191822138

这也就是为什么静态资源不用重启项目就能生效

11. MIME类型

MIME是 HTTP协议中数据类型。MIME的英文全称是Multipurpose Internet MailExtensions多功能Internet邮件扩充服务。MIME类型的格式是"大类型/小类型",并与某一种文件的扩展名相对应

在响应包的Content-Type就有指定

image-20240122192203353

常见的MIME类型

image-20240122192218363