Servlet原理学习

news2024/12/26 23:22:49

一、网站架构和Servlet技术体系架构

1.网站架构

在这里插入图片描述
现在的网站架构分为 B/S架构和C/S的架构两种。
这种“B/S”结构有很多好处,维护和升级方式更简单,客户端是浏览器,基本不需要维护,只需要维护升级服务器端就可以,
C/S结构是一种软件系统体系结构,也是生活中很常见的。这种结构是将需要处理的业务合理地分配到客户端和服务器端,这样可以大大降低通信成本,但是升级维护相对困难。

2.技术体系

在这里插入图片描述

二、tomcat实现静态资源访问

1.创建项目

.在webapps中创建问价夹,比如myweb(这个文件夹就是我们的项目)
.创建WEB-INF文件夹,用于存放项目的核心内容
.创建classes文件夹,用于存放.class文件
.创建lib,存放jar包
.创建web.xml,项目配置文件(到ROOT项目下的WEB-INF复制过来即可)
.将网页xxx.html复制到myweb项目中,与WEB-INF在同级。

2.启动tomcat,访问项目

在浏览器当中输入:http://localhost:8080/myweb/myfirst.html

三、创建第一个servlet项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、创建Servlet

1.什么是Servlet

Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类, 一般情况下,人们将Servlet理解为后者。
广义
在这里插入图片描述
狭义
在这里插入图片描述

2.编写第一个Servlet

①:编写Servlet

  • 实现servlet接口
  • 重写5个主要方法
  • 在servlet()方法中编写输出语句
    在这里插入图片描述
    在这里插入图片描述

②:部署配置访问servlet

  • 将写好的servlet程序编译成.class文件
    在这里插入图片描述
  • 将.class文件放置到WEB-INF下边的classes文件当中去
    在这里插入图片描述
  • 配置web.xml
    在这里插入图片描述
  • 启动tomcat并完成访问
    访问路径:http://localhost:8080/myweb/myservlet
    在这里插入图片描述
    在这里插入图片描述

五、Http协议

1.认识url

url被称为统一资源定位符,用来表示从互联网上得到的资源位置和访问这些资源的方法。
他的表示方法一般为:

<协议>://<主机>:<端口>/<路径>

如下我们启动一个servlet程序,来看一下我们的url表示:

http://localhost:8080/BuyechengServlet/login.html

大家可以看到我们采用的是我们这里采用的是 http协议
localhost:代表的是我们本机的IP地址
8080:代表我们的端口号
BuyechengServlet/login.html :代表的是我们的路径。

协议部分 确定了我们的浏览器怎样向浏览器发送请求,以及服务器应该怎样反馈我们的请求,除了HTTP协议以外还有FTP协议和DNS协议等。
主机部分 一般是我们的ip地址,localhost指的我们本地的IP地址,也可以用127.0.0.1来代替。当然这个部分使用的最多的还是域名的方式,比如www.baidu.com等等都属于域名。我们在计算机网络当中是通过ip地址来进行寻址的,那么就需要把域名解析成ip地址,解析的工具就是我们上课节说的DNS服务器。
端口部分 一般采用的是80端口号,而我们上边所使用的的8080端口号,是tomcat默认的端口号。
端口号的存在是为了我们相关的进程能够有及时的从计算机网卡当中拿到属于自己的数据。每一个进程都有一个属于自己的端口号,且不能重复。每一个到达网卡的数据都必须带有响应的端口号,以便能够请求响应的进程。
路径部分 的主要作用是起到资源定位的作用,定位相关的资源,以便于我们能够及时的处理资源。

2.超文本传输协议http

超文本传输协议(http),是关于在网络上如何传输超级文本(既HTML文档)的协议。http规定了Web(广域网)基本运作过程,以及浏览器和web服务器之间的通信细节。HTTP规定Web的基本运作过程是基于客户/服务器的通信模式,客户端主动发起HTTP请求,服务器端主动接受HTTP请求,在返回响应的http响应结果。
在这里插入图片描述

3.http协议的请求和相应

①.HTTP请求格式

一个http请求一般由一下三部分组成
在这里插入图片描述

  • 请求方式、url和Http版本
    HTTP的请求方式有很多种,这里只讲解两种,既get和post
    GET:
1.通过Url传递参数,Url与参数之间用?隔开,多个参数用&隔开,也是表单的默认提交方式。
2.Get传送的数据量较小,这主要是因为收到url长度的限制
3.Get会将数据显示到URL当中不安全
4.Get一般用于直接获取数据,提高查询速度

POST:

1.post的数据在请求主体内,所以相比安全
2.post对上传数据的大小无限制
3.post适用于增删改操作
  • 请求头
Accept-Encoding: gzip, deflate, br    #浏览器所用的语言
Host: www.baidu.com                   #远程主机
Cookie:                               # cookie
User-Agent:                           #浏览器类型
  • 请求正文
wd=csdn&rsv_spt=1&rsv_iqid=0xcc9c81290004bde9&issp=1

②.HTTP响应格式

在这里插入图片描述

  • 状态
200:响应成功
400:错误的请求,客户发送的HTTP请求不正确
404:文件不存在,访问的url地址不对
405:服务器不支持客户的请求方式
500:服务器内部错误
  • 响应头
    在这里插入图片描述
  • 响应正文
<html>
    <head>
        <title>qcby</title>
    </head>
    <body>
         <h1>qcby</h1>
    </body>
</html>

4.无状态的http协议

当用户访问web应用时,在许多情况下,web服务器必须能够跟踪用户的状态。比如许多用户在购物网站上购物,Web服务器为每个用户配置了虚拟的购物车。当某个用户请求将一件商品放入购物车时,web服务器必须根据发出请求的用户身份,找到客户的购物车,将商品放入其中。之所以能够完成这样的操作不是因为http协议拥有能够记录用户身份的功能。HTTP是无状态的协议。所谓的无状态,是指当浏览器与服务器之间进行基于http协议进行通信时,HTTP没有提供服务器持续跟踪特定浏览器端的规范。 上诉操作之所以能完成是因为http的会话管理机制。
会话: 双方都带有对方的标记,通讯的时候根据带着的标记进行识别。这个会话跟打电话原理一样的,双方手机网卡记录对方标记,每次带着标记通话,两端都存着好多电话号码就跟存了好多标记一样。

六、servlet核心接口和类

在Servlet体系中,除了实现servlet接口,还可以通过继承GenericServlet或HttpServlet类实现编写

1.Servlet接口

servlet接口是整个servlet的核心。它是所有Servlet类必须直接或者间接实现的一个接口,其内部需要实现的5个方法分别关乎着我们servlet的生命周期和业务实现。

init(... )  当Servlet第一次被请求时,Servlet容器就会开始调用这个方法来初始化一个Servlet对象出来  
service(...)  每当请求Servlet时,Servlet容器就会调用这个方法
destroy(...) 当要销毁Servlet时,Servlet容器就会调用这个方法
getServletInfo( ...) 这个方法会返回Servlet的一段描述,可以返回一段字符串。
getServletConfig(... )这个方法会返回由Servlet容器传给init( )方法的ServletConfig对象。

2.servlet的生命周期

由于servlet本身没有main()方法,不能独立运行,他的运行完全由Servlet容器来进行控制和调度。Servlet 生命周期可被定义为从创建直到毁灭的整个过程。

 @WebServlet(value="/s01")
public class Servlet01 implements Servlet{

	@Override
	public void init(ServletConfig config) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println("初始化时调用");
	}

	@Override
	public ServletConfig getServletConfig() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("开启服务时调用");
	}

	@Override
	public String getServletInfo() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("销毁时调用");
	}
	
}

在这里插入图片描述

3.GenericServlet抽象类

GenericServlet实现了servlet接口,并且实现了init()和destroy()方法,简化了我们的开发流程

①:实现GenericServlet

在这里插入图片描述

②:配置web.xml,完成对程序的访问

在这里插入图片描述

4.HttpServlet类

HttpServlet是继承了GenericServlet类,这是一个抽象类。因为我们的请求一般都是Http请求,为了匹配Http请求,于是就有了HttpServlet。为了能够更加方便的处理来自浏览器的数据和将数据写会到浏览器,HttpServlet类引用了HttpServletRequst和HttpServletResponse两个类来处理和相应数据。

①:实现HttpServlet

在这里插入图片描述

②:配置web.xml,完成对程序的访问

在这里插入图片描述
用get的方式进行访问
在这里插入图片描述
在这里插入图片描述
用post的方式进行访问
在这里插入图片描述
在这里插入图片描述

5.Servlet线程安全问题

①:线程安全问题

当我们访问servlet的时候,我们需要执行实例化操作,创建一个servlet对象。而我们tomcat容器可以让多个线程并发访问Servlet,如果在方法当中对成员变量做修改,就会出现线程安全问题。
在这里插入图片描述

https://note.youdao.com/s/BpR4V2nD

②:如何保证线程安全

  • synchronized :这种方式会大量的造成线程堵塞
    在这里插入图片描述
  • 实现SingleThreadModel接口
    servlet实现SingleThreadModel接口后,每个线程都会创建servlet实例,这样每个客户端就不存在线程资源共享资源的问题,但是servlet响应客户端请求效率太低,所以淘汰。
    在这里插入图片描述
  • 尽可能使用局部变量
    在这里插入图片描述

七、servlet的两种配置访问方式

1.Servlet使用Web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
            xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
            id="WebApp_ID" version="3.1">

	<servlet>
		<servlet-name>my</servlet-name>
		<servlet-class>com.qcby.MyServlet</servlet-class>
		<!-- 启动的优先级,数字越小越先启动 -->
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>my</servlet-name>
		<url-pattern>/myservlet</url-pattern>
	</servlet-mapping>
	
	<servlet>
		<servlet-name>second</servlet-name>
		<servlet-class>com.qcby.SecondServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>second</servlet-name>
		<url-pattern>/second</url-pattern>
	</servlet-mapping>
</web-app>

①:url-pattern定义的匹配规则说明

在这里插入图片描述

②:load-on-startupt

在这里插入图片描述

2.Servlet使用注解配置(推荐)

@WebServlet注解常用属性

  • name:Servlet文件的名称(可选)
  • value:配置url路径,可以配置多个
    在这里插入图片描述
  • urlPatterns: 配置url路径,和value作用一样,不能同时使用
    在这里插入图片描述
  • loadOnStartup: 配置servlet的创建时机
    在这里插入图片描述

八、servlet应用【重点】

1.request对象

当客户端向服务器端发送请求时,服务器为本次请求创建request对象,并在调用Servlet的service方法时,将该对象传递给service方法。Request对象中封装了客户端发送过来的所有的请求数据。
在这里插入图片描述

①:doGet()方法接收request数据

  • 编写html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="/SecondServlet/regist" method="get"> 
		用户名:<input type="text" name="username"/>
		密码:<input type="text" name="password"/>
		<input type="submit" value="注册">
	</form>
</body>
</html>
  • 编写doGet()方法
@WebServlet("/regist")
public class RegistServlet  extends HttpServlet{
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String username = req.getParameter("username");
		String password = req.getParameter("password");
		
		System.out.println(username + " " + password);
	}
}

②:doPost()方法接收request数据

  • 编写html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="/SecondServlet/regist" method="post"> 
		用户名:<input type="text" name="username"/>
		密码:<input type="text" name="password"/>
		<input type="submit" value="注册">
	</form>
</body>
</html>
  • 编写doPost()方法
@WebServlet("/regist")
public class RegistServlet  extends HttpServlet{
	
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String username = req.getParameter("username");
		String password = req.getParameter("password");
		
		System.out.println(username + " " + password + "dopost");
	}

}

③:请求乱码问题

由于request是接收来自用户的请求,服务器会根据编码格式将请求转换。服务器端默认的编码格式为ISO-8859-1(此编码不支持中文),而我们用户浏览器默认是utf-8的编码格式,所以往往会产生乱码。要想解决乱码问题,需要设置request当中的编码格式,告诉服务器以何种形式来解析数据。或者在接收到乱码以后,通过何种编码格式进行还原
方式一:

request.setCharacterEncoding("UTF-8");

该方法只针对POST有效(必须在接收数据之前设定)
方式二:

new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8"));

借助String对象的方法,该种方式对任何请求有效,都是通用的。
Tomcat8以后的get请求时不会出现乱码的。

④:转发请求【重点】

请求转发是一种服务器行为,当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的url地址不会发生改变,得到相应后,服务器端会将请求发送给客户端,从始至终只有一个请求发出。

request.getRequestDispatcher(url).forward(request, response);

具体实现,定义两个servlet

/**
 * 
 * @author lenovo
 *         请求转发跳转
 *                 可以让服务器端跳转到客户端(或者指定的(Servlet)
 *           特点:	
 *     1.服务器端行为      
 *     2.地址栏不会发生改变
 *     3.从始至终都是一个请求
 *     4.request当中的数据在servlet程序中共享
 */
@WebServlet(value="/s01")
public class Servlet01 extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String username  = req.getParameter("username");
		String password = req.getParameter("password");
		System.out.println("s01="+username + " " + password);
		// 请求跳转到Servlet02
		//req.getRequestDispatcher("s02").forward(req, resp);
		//请求发送到html页面
		req.getRequestDispatcher("RegistServlet.html").forward(req, resp);
	
	}
}
@WebServlet(value="/s02")
public class Servlet02 extends HttpServlet{
      @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	// TODO Auto-generated method stub
    	  String username  = req.getParameter("username");
  		String password = req.getParameter("password");
  		System.out.println("s02=" + username + " " + password);
    }
}

运行起来我们发现s01和s02都会输出,且只是请求了一次
在这里插入图片描述
在这里插入图片描述

⑤:request作用域[重点]

request表示一个请求,只要发出一个请求就会创建一个request对象,他的作用域:仅在当前请求中有效。
用处:常用于服务器间同一请求不同页面之间的参数传递,常用于表单的控制值传递。
常用的方法
在这里插入图片描述
使用方式:给Servlet传值

@WebServlet("/s03")
public class Servlet03 extends HttpServlet{
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("我是03");
		req.setAttribute("user", "qcby");
    	req.setAttribute("age", 18);              		
    	req.getRequestDispatcher("s04").forward(req, resp);
	}
}

@WebServlet("/s04")
public class Servlet04 extends HttpServlet{
      @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	// TODO Auto-generated method stub
    	System.out.println("我是04");
    	System.out.println(req.getAttribute("user"));
    	System.out.println(req.getAttribute("age"));
    }
}

访问:http://localhost:8080/SecondServlet/s03
在这里插入图片描述

2.response对象

在这里插入图片描述

①:response的主要方法

在这里插入图片描述
getWriter()

@WebServlet("/regist")
public class RegistServlet  extends HttpServlet{
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		PrintWriter printWriter = resp.getWriter();
		printWriter.print("success");
	}
}

getOutputStream()

@WebServlet("/regist")
public class RegistServlet  extends HttpServlet{
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		// PrintWriter writer = resp.getWriter();
		// writer.print("success");
		ServletOutputStream stream  = resp.getOutputStream();
		stream.write("Success".getBytes());
	}
}

html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="/SecondServlet/regist" method="post"> 
		用户名:<input type="text" name="username"/>
		密码:<input type="text" name="password"/>
		<input type="submit" value="注册">
	</form>
</body>
</html>

在这里插入图片描述

②:响应乱码问题

浏览器与服务器传输中文数据会乱码,原因就是服务器响应数据默认采用iso-8859-1码表,浏览器默认采用utf-8码表,所以就会乱码。
要解决该乱码只能在服务器端告诉服务器使用一种能够支持中文的编码格式,比如UTF-8

response.setCharacterEncoding("UTF-8");

此时还只是完成了一半的工作,要保证数据的正确显示,还要指定客户端的编码方式

response.setHeader("content-type", "text/html;charset=UTF-8");

两端指定编码后,乱码就解决了,一句话:保证发送端和接收端的编码一致
以上两句话可以简化为一句话,同时指定客户端和服务器端

response.setContentType("text/html;charset=utf-8");

案例

@WebServlet(value="/s01")
public class Servlet01 extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.setContentType("text/html;charset=utf-8");
		PrintWriter writer = response.getWriter();
		writer.append("<h1>你好</h1>");
	}
}
@WebServlet(value="/s01")
public class Servlet01 extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.setContentType("text/html;charset=utf-8");
		ServletOutputStream outputStream = response.getOutputStream();
		outputStream.write("<h1>你好</h1>".getBytes());

	}
}

③:重定向

重定向是一种服务器指导,客户端行为。客户端发出第一个请求,被服务器接收处理后,服务器会给客户端一个响应(一个新的地址),当客户端接收到新的请求后,会立刻马上根据服务器发送来的地址发起第二次请求。服务器接收请求并完成响应,重定向完成。
从上述描述中可以看出重定向存在两次请求,并且是客户端行为:

response.sendRedirect(url); 

案例

@WebServlet("/s05")
public class Servlet05 extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("我是s05");
		// 重定向到s06
		response.sendRedirect("s06"); 
	}
}
@WebServlet("/s06")
public class Servlet06 extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("我是s06");
	}
}

我们进行请求
当我们输入:http://localhost:8080/SecondServlet/s05,我们会返现地址栏会发生改变
在这里插入图片描述
打开f12我们会发现我们访问了s05和s06,并且s05页面的状态是302,目标地址是s06
在这里插入图片描述

3.请求转发和重定向的区别

在这里插入图片描述
重定向到百度

@WebServlet("/s05")
public class Servlet05 extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("我是s05");
		
		// 重定向到s06
		response.sendRedirect("http://www.baidu.com"); 
	}
}

九、状态管理

1.现有问题

  • Http是无状态的,不能保存每次提交的信息
  • 如果用户发来一个新的请求,服务器无法知道它是否与上次请求是否有联系.
  • 对于那么需要提交多次信息才能完成的操作,比如购物,就很有问题

2.概念

  • 将浏览器和web服务器之间多次交互当成一个整体来处理,并且将多次交互所涉及的数据(即状态)保存先来。

3.状态管理分类

  • 客户端状态管理:将状态保存在客户端。代表性技术就是Cookie技术
  • 服务器状态管理: 将状态保存在服务端,代表性技术就是Session技术

十、Cookie的使用

1.什么是cookie

Cookie是服务器发送到用户浏览器并保持在本地的一小块信息,他会在浏览器下次向服务器发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器。
在这里插入图片描述

2.cookie的基本操作

@WebServlet("/cs")
public class CookieServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//1.服务端创建cookie对象
		Cookie cookie = new Cookie("username", "qcby");
       //2.设置cookie有效期 1 小时  
      cookie.setMaxAge(60*60);  // 存储数据有三种方式:>0有效期,单位秒;=0浏览器关闭;<0 临时存储,默认为-1
		//3.将cookie响应给客户端
		resp.addCookie(cookie);
	}
}

访问:http://localhost:8080/SecondServlet/cs
查看cookie
我们可以在chrome浏览器的设置—>隐私设置和安全性中找到查看Cookie和网站数据
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.cookie的获取

浏览器jquary获取cookie

function getCookie(cname){
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for(var i=0; i<ca.length; i++) {
        var c = ca[i].trim();
        if (c.indexOf(name)==0) { return c.substring(name.length,c.length); }
    }
    return "";
}

服务器获取cookie的值

@WebServlet("/getCookie")
public class GetCookieServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 通过request对象获取所有的cookie
		Cookie[] cookies = req.getCookies();
		// 通过for循环遍历cookie
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				System.out.println(cookie.getName() + " " + cookie.getValue());
			}
		}
	}
}

4.Cookie的编码和解码

cookie默认不支持中文,只能包含ASCII码。所以cookie需要对Uncode字符进行编码,否则会出现乱码

①:创建带有中文的cookie

@WebServlet("/cs")
public class CookieServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//1.服务端创建cookie对象
		Cookie cookie = new Cookie(
				URLEncoder.encode("姓名","UTF-8"),
				URLEncoder.encode("张三","UTF-8")
				);
	        //2.设置cookie有效期 1 小时
	        cookie.setMaxAge(60*60);
		//3.将cookie响应给客户端
		resp.addCookie(cookie);
	}
}

②:解码带有中文的cookie

@WebServlet("/getCookie")
public class GetCookieServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 通过request对象获取所有的cookie
		Cookie[] cookies = req.getCookies();
		// 通过for循环遍历cookie
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				System.out.println(URLDecoder.decode(cookie.getName(),"UTF-8")+" " + URLDecoder.decode(cookie.getValue(),"UTF-8"));
			}
		}
	}
}

5.cookie的优缺点

优点

  • 可配置到期规则
  • 简单性:cookie是一种包含文本轻量结构,包含简单的键值对
  • 数据持久性:cookie默认在过期之前可以一直保存在客户端浏览器上

缺点:

  • 大小受限制:大多数浏览器对cookie的大小有限制,分别是4k和8k字节
  • 用户配置为禁用:有些用户禁用了浏览器或者客户端设备接收cookie的能力,因此限制了这一功能
  • 潜在的安全风险:Cookie可能被篡改

十一、Session对象(重点)

1.Session概述

  • Session用于记录用户的状态。Session是指在一段时间之内,单个客户端与Web服务端的一连串的交互过程。
  • 在一个Session中,客户可能会多次请求访问各种不同的服务器资源。
    在这里插入图片描述

2.Session原理

  • 服务器会为每一次会话分配一个Session对象
  • 同一浏览器发起的多次请求,同属于一次会话(Session)
  • 首次使用Session时,服务器会自动创建session,并创建Cookie存储SessionId发送回客户端
    在这里插入图片描述

3.Session的使用

①:获取session

@WebServlet("/ss")
public class CookieServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 1. 通过request对象获取Session对象
		HttpSession session = req.getSession();
		// 获取sessionid
		System.out.println(session.getId());
	}
}
 

我们使用浏览器对网站进行访问,我们会发现打印
在这里插入图片描述
在浏览器当中会有
在这里插入图片描述
当我们关闭浏览器,重新打开访问项目我们会发现session变了
在这里插入图片描述

②:Session保存数据

setAttribute(“key”, value)保存数据到session中

session.setAttribute("key", value); //以键值对的形式存储在session当中

③:Session获取数据

getAttribute(“key”)获取session中的数据

session.getAttribute("key");  // 通过String类型的key访问Object类型的value

④:Session移除数据

removeAttribute(“key”)从session中删除数据

session.removeAttribute("key"); // 通过key值删除session中的值

4.Session的生命周期

  • 开始:第一次使用到session的请求产生则创建session
  • 结束
    *浏览器关闭
    *session超时失效
    session.setMaxInactiveInterval(interval)
    *手动销毁失效
    session.invalidate();
    *服务器关闭

5.浏览器禁用Cookie后使用Session解决方案

浏览器在默认情况下,会使用cookie的方式将sessionID发送给服务器,如果用户禁用Cookie,则sessionID不会被浏览器保存,此时浏览器可以使用URL重写这样的方式发送sessionID
①:URL重写
浏览器在访问服务器上的某个地址时,不在使用原来的地址,而是使用经过该写的地址(在原来的地址上边加上sessionID)
②:实现URL重写
response.encodeRedirectURL(url)

@WebServlet("/ss")
public class SetSession extends HttpServlet{
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		HttpSession session = request.getSession();
		// 重写 URL 追加 SessionID
		String newUrl = response.encodeRedirectURL("/SecondServlet/gs");
		System.out.println(newUrl);
		response.sendRedirect(newUrl);  //重定向到我们要跳转页servlet
	}
}
@WebServlet("/gs")
public class GetSession extends HttpServlet{
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		// 1. 通过request对象获取Session对象
		HttpSession session = req.getSession();
		// 获取sessionid
		System.out.println(session.getId());
	}
}

输出
在这里插入图片描述
实际情况是我们在url上边加上了sessionID
在这里插入图片描述

十二、ServletContext对象

1.ServletContext概述

每一个web程序都有且仅有一个servletContext对象,又称Application对象,从名称当中可知,该对象与应用程序有关。在WEB容器启动时,会为每一个应用程序创建一个ServletContext对象。
该对象有两大作用:
第一:作为域对象来共享数据,此数据在整个应用程序中共享;
第二:该对象中保存了当前应用程序相关信息。例如可以通过getServletInfo()方法获取当前服务器信息,getRealPath()获取资源的真实路径等。

2.ServletContext对象获取

获取servletContext对象的途径有很多。比如:

①.通过request对象获取

ServletContext servletContext = req.getServletContext();

②.通过session对象获取

ServletContext servletContext = request.getSession().getServletContext();

③.通过servletConfig对象获取,在Servlet标准中提供了ServletConfig方法

ServletContext servletContext = getServletConfig().getServletContext();

④.直接获取 Servlet类中提供了直接获取ServletContext对象的方法

ServletContext servletContext = getServletContext();

基本使用

@WebServlet("/SC")
public class ServletCon extends HttpServlet{
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
		ServletContext servletContext = getServletContext();
		//常用方法
		//获取当前服务器的版本信息
		String ServletInfo = servletContext.getServerInfo();
		System.out.println("服务器当前的版本信息:" + ServletInfo);
		//获取项目的真实路径
		String realPath = servletContext.getRealPath("/");
		System.out.println("获取项目的真实路径:" + realPath);
	}
}

3.ServletContext域对象

ServletContext也可以当做域对象来使用,通过ServletContext中存取数据,可以使得整个应用程序共享某些数据。当然不建议存放过多数据,因为ServletContext中的数据一旦存储进去没有手动移除会将一直保存。

@WebServlet("/SC")
public class ServletCon extends HttpServlet{
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
		ServletContext servletContext = getServletContext();
		// 设置域对象
		servletContext.setAttribute("name", "张三");
		// 获取域对象
		String name = (String) servletContext.getAttribute("name");
		System.out.println(name);
		// 移除域对象
		servletContext.removeAttribute("name");
	}
}

总结:Servlet三大作用域

1.request域对象

在一次请求中有效。请求转发有效,重定向失败

2.session域对象

在一次会话中有效。请求转发和重定向都有效,session销毁后失效

3.servletContext域对象

在整个应用程序中有效。服务器关闭销毁。

十三、过滤器【重点】

过滤器是处于客户端与服务器资源之前的一道过滤技术
在这里插入图片描述

1.过滤器作用

过滤器执行在Servlet之前,客户端发送请求时,会先经过过滤器Filter,在到达目标Servlet当中。从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

2.编写过滤器

  • 编写java类实现Filter接口
  • 在doFilter方法中编写拦截逻辑
  • 设置拦截器

拦截器代码

@WebFilter("/tage")  //设置拦截的目标,也及时该目标的访问地址
public class MyFilter implements Filter{
	// 初始化方法
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("执行拦截器");
		// 让请求继续执行到拦截的servlet当中去
		chain.doFilter(request, response);
  		//执行完毕返回
		System.out.println("执行完毕返回");  		     
	}
	
	//效果方法
	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

}

目标代码

@WebServlet("/tage")
public class TageServlet extends HttpServlet{
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		System.out.println("我是目标servlet");
		
	}

}

html访问

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="/ServletTest/tage" method="get">
		<input type="submit" value="登录"/>
	</form>
</body>
</html>

在这里插入图片描述

3.在web.xml中配置过滤器

过滤器代码

public class MyFilter implements Filter{

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		
		System.out.println("我执行啦 ");
		//继续执行剩下的过滤器
        chain.doFilter(request, response);  //让目标资源执行,放行
		
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}
}

xml当中的配置

<!--配置过滤器-->
   <filter>
       <filter-name>myFilter</filter-name>
       <!-- 过滤器类全名 -->
       <filter-class>com.qcby.MyFilter</filter-class>
   </filter>
   
   <!--映射过滤器-->
   <filter-mapping>
       <filter-name>myFilter</filter-name>
       	<!--拦截规则 -->
       <!--/*”表示拦截所有的请求 -->
       <url-pattern>/*</url-pattern>
   </filter-mapping>

4.关于拦截路径

拦截器的拦截路径通常有三种方式
    精确匹配拦截:比如/index.jsp  /tage  
    后置匹配拦截:比如*.html   *.jsp
    通配符拦截匹配/* 表示拦截所有。注意过滤器不能使用 / 匹配

5.过滤器链和优先级

客户端对服务器请求后,服务器在调用Servlet之前会调用一组过滤器(多个过滤器),那么这组过滤器就称为一组过滤链。
每个过滤器都有特定的功能,当一个过滤器的doFilter()方法被被调用后,Web服务器会创建一个代表Filter链的FilterChain对象传递该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter()方法,则Web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。
在这里插入图片描述

在一个web应用当中,可以开发编写多个Filter,这些Filter组合起来称为一个Filter链。
优先级:
    1.如果为注解的话,是按照全类程序的字符串顺序决定作用顺序
    2.如果是web.xml,按照filter-mapping注册顺序,从上到下
    3.web.xml配置高于注解方式
    4.如果注解和web.xml同时配置,会造成多个过滤对象,造成多次过滤

6.过滤器典型应用

①:乱码处理—dopost的乱码处理

拦截器

@WebFilter(value="/login")
public class EncodingFilter implements Filter{

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
 		
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=utf-8");
		System.out.println("----------");
		chain.doFilter(request, response);  //让目标资源执行,放行
	}

	@Override
	public void destroy() {
		
		
	}

}

登录servlet

 @WebServlet("/login")
public class Login extends HttpServlet{
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
		String username = request.getParameter("username");
		String password = request.getParameter("password");

		System.out.println(username + " " + password);
		
		
	}

}

html页面

	<form action="/ServletTest/login" method="post">
		用户名:<input type="text" name="username"/><br/>
		密码:<input type="text" name="password"/><br/>
		<input type="submit" value="登录"/>
	</form>

②:权限验证

首先是关于登录:登录完成之后设置sessionid

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
	用户名:<input type="text" name="username"/><br/>
		密码:<input type="text" name="password"/><br/>
		<input type="submit" value="登录" onclick ="get()"/>
</body>
<script>
	function get(){
		var username = $("#username").val();
		var password = $("#password").val();
		$.ajax({
			type:'post',  // 提交的类型 get--->doGet /  post---->doPost
			url:"/ServletTest/login", // url:统一资源定位符
			data:{"username":username,"password":password}, // 传输的数据
			success:function(data){ // 数据接收
				console.log(data);
				if(data.code=="200"){
					window.location.href = "/ServletTest/content.html";
				}
			}
		})
	}
</script>
</html>

servlet

		// TODO Auto-generated method stub
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		
		System.out.println(username + " " + password);
		
		//登录成功以后,讲登录信息防伪session当中
		HttpSession session = request.getSession();
		session.setAttribute("name", session.getId());
		System.out.println(session.getAttribute("name"));
		
		response.setContentType("text/json;charset=UTF-8");
		response.setCharacterEncoding("utf-8");
		//登录成功以后向前台返回数据
		String json = "{\"code\":\"200\",\"message\":\"成功\"}";
		response.getWriter().append(json);

并跳转到content页面当中

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body onload="get()">
	<!-- 数据显示位置 -->
    <div id="inf"></div>
</body>
<script>
	function get(){
		$.ajax({
			type:'get',  // 提交的类型 get--->doGet /  post---->doPost
			url:"/ServletTest/target", // url:统一资源定位符
			data:{}, // 传输的数据
			success:function(data){ // 数据接收
				console.log(data);
				viewList(data);
			}
		})
	}
	function viewList(data){
		  var html = '<table border="1">';
		  html += '<tr>';
		 	  html += '<th>id</th>';
		 	  html += '<th>姓名</th>';
			  html += '<th>性别</th>';
			  html += '<th>年龄</th>';			 
		  html += '</tr>';
		  for(var i = 0;i<data.length;i++){
			  html += '<tr>';
			  html += '<td >' +data[i].id+ '</td>'; 
			  html += '<td >' +data[i].name+ '</td>'; 
			  html += '<td >' +data[i].sex+ '</td>'; 
			  html += '<td >' +data[i].age+ '</td>';
			  html += '</tr>';
		  }
		  html += '</table>';
		  $("#inf").empty().append(html);
	}
</script>
</html>

servlet

@WebServlet("/target")
public class MyServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		resp.setContentType("text/json;charset=UTF-8");
		resp.setCharacterEncoding("utf-8");
		String json = "\r\n" + 
				"[\r\n" + 
				"	{\"id\":\"1\",\"name\":\"张三\",\"sex\":\"男\",\"age\":\"18\"},\r\n" + 
				"	{\"id\":\"2\",\"name\":\"里斯\",\"sex\":\"男\",\"age\":\"18\"},\r\n" + 
				"	{\"id\":\"3\",\"name\":\"王五\",\"sex\":\"男\",\"age\":\"18\"},\r\n" + 
				"	{\"id\":\"4\",\"name\":\"李留\",\"sex\":\"男\",\"age\":\"18\"}\r\n" + 
				"]";
		resp.getWriter().append(json);
	}
}

关于权限验证:当我们直接打开content.html页面的时候我们不能直接获取数据

@WebFilter("/target")
public class CheakFilter implements Filter{

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// 如果登录过那么久跳转到MyServlet当中去,如果没有就跳转到登录
		// 向下转型
		HttpServletRequest request2 = (HttpServletRequest)request;
		HttpServletResponse response2 = (HttpServletResponse) response;
		//创建session对象
		HttpSession session = request2.getSession();
		String name = (String) session.getAttribute("name");
		if (name !=null) {
			chain.doFilter(request, response);
		}else {
			System.out.println("请先登录....");
			response2.sendRedirect(request2.getContextPath() + "/login.html");
		}
		
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1457573.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[AudioRecorder]iPhone苹果通话录音汉化破解版-使用巨魔安装-ios17绕道目前还不支持

首先你必须有巨魔才能使用&#xff01;&#xff01; 不会安装的&#xff0c;还没安装的移步这里&#xff0c;ios17 以上目前装不了&#xff0c;别看了&#xff1a;永久签名 | 网址分类目录 | 路灯iOS导航-苹果签名实用知识网址导航-各种iOS技巧-后厂村路灯 视频教程 【Audio…

并发List、Set、ConcurrentHashMap底层原理

并发List、Set、ConcurrentHashMap底层原理 ArrayList: List特点&#xff1a;元素有放入顺序&#xff0c;元素可重复 存储结构&#xff1a;底层采用数组来实现 public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Clon…

【医学大模型 补全主诉】BioGPT + LSTM 自动补全医院紧急部门主诉

BioGPT LSTM 自动补全医院紧急部门主诉 问题&#xff1a;针对在紧急部门中自动补全主诉的问题子问题1: 提高主诉记录的准确性子问题2: 加快主诉记录的速度子问题3: 统一医疗术语的使用子问题4: 减少打字错误和误解子问题5: 提高非特定主诉的处理能力 解法数据预处理神经网络方…

选择结构switch

一、执行流程 所有case都和表达式的值不匹配&#xff0c;就会执行default语句体部分 从被匹配的位置开始执行&#xff0c;如果遇到break&#xff0c;那么退出选择结构 二、注意事项 1、case后面的【常量值】不能重复&#xff0c;不然编译器会报错 2、switch后面的小括号只…

数字化转型导师坚鹏:政府数字化转型之数字化技术

政府数字化转型之数字化技术 ——物联网、云计算、大数据、人工智能、虚拟现实、区块链、数字孪生、元宇宙等综合解析及应用 课程背景&#xff1a; 数字化背景下&#xff0c;很多政府存在以下问题&#xff1a; 不清楚新技术的发展现状&#xff1f; 不清楚新技术的重要应…

las数据转pcd数据

las数据转pcd数据 一、算法原理1.介绍las2.主要函数 二、代码三、结果展示3.1 las数据3.2 las转换为pcd 四、相关数据链接 一、算法原理 1.介绍las LAS文件按每条扫描线排列方式存放数据,包括激光点的三维坐标、多次回波信息、强度信息、扫描角度、分类信息、飞行航带信息、飞…

【已解决】d:\recording\2A327.mp3 (拒绝访问。)

在用JAVA程序&#xff0c;下载音频到本地文件夹的时候&#xff0c;显示拒绝访问。 一开始我以为是文件夹没有权限&#xff0c;但是在我赋予了写入权限后&#xff0c;仍然出现拒绝访问的提示。 我观察了一下&#xff0c;保存到本地的时候&#xff0c;多写了一层文件夹。因为到这…

【Git】:初识git

初识git 一.创建git仓库二.管理文件三.认识.git内部结构 一.创建git仓库 1.安装git 使用yum install git -y即可安装git。 2.创建仓库 首先创建一个git目录。 3.初始化仓库 这里面有很多内容&#xff0c;后面会将&#xff0c;主要是用来进行追踪的。 4.配置name和email 当然也…

WEB服务器的超级防护——安全WAF

随着网络和信息技术的不断发展&#xff0c;特别是互联网的广泛普及和应用&#xff0c;网络正在逐步改变人类的生活和工作方式。越来越多的政府和企业组织建立了依赖于网络的业务信息系统&#xff0c;例如电子政务、网络办公等。网络也对社会各行各业产生了巨大的影响&#xff0…

【Java基础知识(1)】对象在内存中的存储

Java对象是如何在内存中存储的&#xff1f; 在Java中&#xff0c;所有的对象被动态地分配在堆中。这和C不同&#xff0c;C允许对象被存储在堆或者栈中。 参考Oracle官方文档&#xff1a;官方文档说明 在Java中创建字符串对象的2种方法&#xff1a; 1、 使用String关键字&am…

Uiautomator2实现Android自动化测试详解

目录 1、UIautomator2框架原理 2、UIautomator2使用 2.1、安装 2.2、元素定位工具-weditor 2.3、设备连接 2.4、全局配置 2.4.1、通过settings设置 2.4.2、通过属性设置 2.5、APP相关操作 2.5.1、安装应用 2.5.2、启动应用 2.5.3、等待应用启动 2.5.4、结束应用 …

【机器学习笔记】 15 机器学习项目流程

机器学习的一般步骤 数据清洗 数据清洗是指发现并纠正数据文件中可识别的错误的最后一道程序&#xff0c;包括检查数据一致性&#xff0c;处理无效值和缺失值等。与问卷审核不同&#xff0c;录入后的数据清理一般是由计算机而不是人工完成。 探索性数据分析(EDA 探索性数据…

从gradient_checkpointing_enable中学习

1.背景 最近在使用官网的教程训练chatGLM3,但是出现了“RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn”错误,查阅了官方的文档,目前这个问题还没什么解决方案 但是其中有人回复说:是注释掉503行的model.gradient_checkpointing_e…

手持三防平板丨国产化加固平板丨国产三防平板发展的意义是什么?

随着现代科技的快速发展&#xff0c;平板电脑在我们的生活中扮演着越来越重要的角色。然而&#xff0c;传统的平板电脑只能在普通的环境中使用&#xff0c;而无法在恶劣的环境中使用&#xff0c;例如在高海拔、高温、高湿度、沙漠等环境中&#xff0c;传统平板电脑往往会出现故…

OpenHarmony—UIAbility组件间交互(设备内)

UIAbility是系统调度的最小单元。在设备内的功能模块之间跳转时&#xff0c;会涉及到启动特定的UIAbility&#xff0c;该UIAbility可以是应用内的其他UIAbility&#xff0c;也可以是其他应用的UIAbility&#xff08;例如启动三方支付UIAbility&#xff09;。 本章节将从如下场…

电脑数据丢失怎么办?5 种免费数据恢复软件能帮到您

我们存储在计算机中的个人和专业数据如果丢失&#xff0c;可能会给我们带来经济和精神上的困扰。有许多情况会导致此类数据丢失&#xff1b;其中一些包括意外删除、硬盘驱动器故障、软件崩溃、病毒攻击等。 5 种最佳免费数据恢复软件 为防止此类事故&#xff0c;建议定期备份计…

智慧城市驿站:智慧公厕升级版,打造现代化城市生活的便捷配套

随着城市化进程的加速&#xff0c;人们对城市生活质量的要求也越来越高。作为智慧城市建设的一项重要组成部分&#xff0c;多功能城市智慧驿站应运而生。它集合了信息技术、设计美学、结构工艺、系统集成、环保节能等多个亮点&#xff0c;将现代科技与城市生活相融合&#xff0…

RK3568平台 有线以太网接口之MAC芯片与PHY芯片

一.平台网络网络通路 平台有线以太网通路&#xff1a;有线以太网一般插入的是RJ45 座要与 PHY 芯片&#xff08;RTL8306M&#xff09;连接在一起&#xff0c;但是中间需要一个网络变压器&#xff0c;网络变压器经过模数转换后到达网卡(RTL8111)转换为帧数据后到达SOC。 二.网络…

【初始RabbitMQ】交换机的实现

交换机概念 RabbitMQ消息传递模型的核心思想就是&#xff1a;生产者生产的消息从不会直接发送到队列。实际上&#xff0c;通常生产者不知道这些消息会传递到那些队列中 相反&#xff0c;生产者只能将消息发送到交换机&#xff0c;交换机的工作内容也很简单&#xff0c;一方面…

Kubernetes基础(二十二)-k8s持久化存储详解

1 volume 1.1 介绍 在容器中的磁盘文件是短暂的&#xff0c;当容器崩溃时&#xff0c;Kubelet会重新启动容器&#xff0c;但容器运行时产生的数据文件都将会丢失&#xff0c;之后容器会以最干净的状态启动。另外&#xff0c;当一个Pod运行多个容器时&#xff0c;各个容器可能…