接口测试 03 -- 接口自动化思维 Requests库应用

1. 接口自动化思维梳理

1.1接口自动化的优点

接口测试自动化,简单来讲就是功能测试用例脚本化然后执行脚本,产生一份可视化测试报告。不管什么样的测试方式,都是为了验证功能与发现 BUG。那为什么要做接口测试自动化呢?一句话概括就是为了节省人力成本。
具体来说,包括以下几点:
● 减轻自己工作量,把测试从枯燥的重复劳动的人工测试中解放出来;
● 协助手工测试完成很难模拟或无法模拟的的工作;
● 提高工作效率,比如测试环境的自动化编译、打包、部署、持续集成甚至持续交付等。
● 协助定位问题,比如接口层发现问题了,可以通过添加的 traceID 定位到日志错误或错误代码行。
●  尽早发现 Bug,自动通知测试人员。 一旦发现问题,立即通知测试人员,快速高效。

1.2 事前准备的主要两个核心

 文档的准备

磨刀不误砍柴工,准备好分详细的接口相关文档能够帮助后续接口自动化测试工作的高效展开。相关文档包括但不限于一下内容:
①《需求文档》明确定义了:接口背后的业务场景,该接口是干什么用的,用到哪里,每次调用会发生什么等;
②《接口文档》明确定义了:接口名,各个入参值,各个返回值,和其他相关信息;
③《UI 交互图》明确定义了:各单页面需展示的数据;页面之间的交互等;
④《数据表设计文档》,明确定义了:表字段规则、表 N 多 N 关系(一对一、一对多、多对多)等;
======================================================================
务必和相关需求方确认好文档中的信息是可靠且最新的,只有依赖可靠的文档才能设计出正确详尽的接口用例,才能得到最正确的结果。

明确接口测试自动化所需功能

① 校验(断言)
测试断言是自动化测试中的测试通过条件,用于判断测试用例是否符合预期。所以支持对返回值校验是一 个必须的功能。
② 数据隔离
数据隔离是指:
具体的请求接口、参数、校验等数据做到与代码相隔离,便于维护,一旦需要调整接口用 例、新增接口用例时可很快速的找到位置。
隔离的另一个好处就是可复用,框架可以推广给其他团队,使 用者可以使用相同的代码,只需要根据要求填写各自用例即可测试起来。
③ 数据传递
做到数据隔离可维护后,数据传递是另外一个更重要的需求。
接口测试时,首先我们会实现单接口解耦, 后续按照业务场景组合多个接口。而数据传递是则是组合多个接口的必要条件,它让接口用例之间可以做 到向下传参。
举个例子:我们通过设备信息查询接口查询到当前天猫精灵音箱的设备信息,该接口会返回 一个 UUID,接下来我们要通过用户信息查询接口去查询当前设备绑定的用户信息,此时第二个接口的请 求数据是需要从第一个接口用例中的返回中提取的
④ 功能函数
实际的业务场景测试会需要各种辅助功能的支持,比如随机生成时间戳,请求 ID,随机的手机号码或位 置信息等等,此时我们就需要代码可以支持做到识别对应关键字时可以执行对应的功能函数进行填充。
⑤ 日志
日志包含执行的具体执行接口、请求方式、请求参数、返回值、校验接口、请求时间、耗时等关键信息, 日志的好处一来是可以便于在新增用例有问题时快速定位出哪里填写有问题,二来是发现 bug 时方便向 开发反馈提供数据,开发可以从触发时间以及参数等信息快速定位到问题所在。
⑥ 可配置
目前测试环境包括但不限于日常、预发一、预发二、线上等等,因此用例不单单只能在一个环境上执行, 需要同一份接口用例可以在日常、预发、线上等多个环境都可以执行。
所以框架需要做到可配置,便于切 换,调用不同的配置文件可以在不同的环境执行。
⑦ 可视化报告
用例执行后,就是到了向团队展示结果的时候了,一个可视化的报告可以便于团队成员了解到每次自动化 接口用例执行的成功数、失败数等数据。
⑧ 可持续集成
对于已经有测试用例并测试完成的接口,我们希望能够形成回归用例,在下一个版本迭代或上线之前,通 过已有用例进行一个回归测试,确保新上线的功能不影响已有功能。
因此,这就需要接口自动化测试是可 持续集成的而不是一次性的。

2. Requests库的基本介绍及安装

2.1 Requests库简介

Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议 的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。

官网介绍:https://cn.python-requests.org/zh_CN/latest/

Requests 也可用于爬虫

2.2 Requests库安装

安装命令:
pip install requests
验证命令:
pip show requests

3. Requests库的实战应用

3.1 Requests库请求源码理解

Requests库常用方法

Requests库常用的方法及对应的参考如下 :
● requests.requests()
● requests.get(‘https://github.com/timeline.json’) :GET请求
● requests.post(“http://httpbin.org/post”) :POST请求
● requests.put(“http://httpbin.org/put”) :PUT请求(提交修改全部的数 据)
● requests.delete(“http://httpbin.org/delete”) :DELETE请求
● requests.head(“http://httpbin.org/get”) :HEAD请求
● requests.patch(“http://httpbin.org/get”) :PATCH请求(提交修改部分 数据)
● requests.options(‘https://github.com/timeline.json’) :OPTIONS请 求(跨域预检请求)

requests方法的请求参数详解

requests.requests(method, url, **kwargs)
● method:请求方式:GET, PUT,POST,HEAD, PATCH, delete, OPTIONS7种方式
● url:网络链接
● kwargs: (13个可选参数)

kwargs可选参数如下:

参数值
参数概述
params
字典或者字节序列,作为参数增加到url中
json
JSON格式的数据,作为requests的内容
headers
字典,HTTP定制头
data
是第二个控制参数,向服务器提交数据,[POST请求用的居多]
cookies
字典或CookieJar, Requests中的cookie
auth
元组,支持HTTP认证功能
files
字典类型,传输文件
timeout
设置的超时时间,秒为单位
proxies
字典类型,设定访问代理服务器,可以增加登录认证
allow_redirects
True/False,默认为True, 重定向开关
stream
True/False,默认为True,获取内容立即下载开关
verity
True/False,默认为True, 认证SSL证书
cert
本地SSL证书路径

3.2 接口测试实战

1. 导入对应的包: import requests
2. 弄清楚对应的接口四要素:接口URL、请求方法、请求参数、响应数据,
3. 把这些内容用代码依次实现。

GET 请求示例

# get()方法的参数
requests.get(url, params=None, **kwargs)
- url: 页面的url链接
- params: url中的额外参数,字典或字节流,非必选

代码示例1:一个简单的get请求

import requestsurl = "http://xxxx.com/"
res = requests.get(url)#获取对应的响应数据:可以对数据格式进行指定
print(res.text)  #text得到的是一个html信息

执行后终端输出一个巨长的html

代码示例二:使用params把分开的url参数、路径拼接到url,实现正常请求

#案例二: 把url参数的环境变量和对应的参数/路径分开
url = "http://xxx.com/"
url_path = "s=api/user/login"
res = requests.get(url, params=url_path)   # 执行的时候会自动把参数拼接到url中
print(res.url)  # 输出的查看url是否是一个正确且完整的url

3.3 常用响应( Response)数据

在接口的响应数据当中,常用用来判断请求参数的如下:
响应参数方法
响应参数概述
r.status_code
响应状态码
r.content
字节方式的响应体,会自动为你解码 gzip 和 deflate 压
r.headers
以字典对象存储服务器响应头,但是这个字典比较特殊,
字典键不区分大小写,若键不存在则返回None
r.json()
Requests中内置的JSON解码器,必须带上()
r.url
获取url
r.encoding
编码格式
r.cookies
获取cookie
r.raw
返回原始响应体
r.text
字符串方式的响应体,会自动根据响应头部的字符编码进
行解码
r.raise_for_status()
失败请求(非200响应)抛出异常

状态码

状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别
1xx:指示信息--表示请求已接收,继续处理
2xx:成功--表示请求已被成功接收、理解、接受
3xx:重定向--要完成请求必须进行更进一步的操作
4xx:客户端错误--请求有语法错误或请求无法实现
5xx:服务器端错误--服务器未能实现合法的请求
常见状态码:
200 OK//客户端请求成功
400 Bad Request//客户端请求有语法错误,不能被服务器所理解
401 Unauthorized//请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden//服务器收到请求,但是拒绝提供服务
404 Not Found//请求资源不存在,eg:输入了错误的URL
500 Internal Server Error//服务器发生不可预期的错误
503 Server Unavailable//服务器当前不能处理客户端的请求,一段时间后可能恢复正常

代码示例

上面提到的所有的Response响应参数方法

语法结构:定义的返回值的接收对象.方法名

部分示例如下:

import requestsurl = "http://xxxx.com/"
url_path = "s=api/user/login"
res = requests.get(url, params=url_path)   # 执行的时候会自动把参数拼接到url中
# print(res.text)
print("url:",res.url)
print("json串:",res.json())
print("状态码:",res.status_code)

反过来说,如果发送请求之后,得到的响应数据不是我想要的呢?

解决思路:
首先把请求数据打印出来
打印请求的语法结构:接收返回值对象.request.方法名

代码示例如下:

import requestsurl = "http://xxxx.com/"
res = requests.get(url)print("查看请求方法:",res.request.method)
print("查看请求url:",res.request.url)
print("查看请求body:",res.request.body)
print("查看请求头:",res.request.headers)

3.4 POST接口测试实战

之前我们一直也在强调,POST的请求参数的类型很多。

而控制它的就是由 请求头当中的 Content-Type 。

所以我们在开发的过程中需要注意客户端发送请求 (Request)时的Content-Type设置,如果设置的不准确,很有可能导致请求失 败,甚至也会返回415错误。

注:415 错误是 Unsupported media type,即不支持的媒体类型。

---------------->>>

一般Content-Type的使用遵守原则:

● 如果普通表单提交:Content-Type:application/x-www-form-urlencoded

● json格式: Content-Type:application/json

● 如果是文件上传:Content-Type:multipart/form-data

案例1:普通表单提交

post请求默认是以form表单提交的

encoding = "utf8"
"""
post请求:登陆接口、
请求参数数据类型x-www-form-urlencoded格式(form表单提交)
接口请求四要素:url、请求方法、请求参数、响应数据
"""
import requests# ur完整的请求l
url = "http://域名/路径/xxx"
# 公共参数
pulic_data = {"application":"app","application_client_type":"weixin"}
# 请求参数:body
data = {"accounts":"hailey","pwd":"hailey123","type":"username"}# ------------------发送请求------------------
res = requests.post(url,params=pulic_data,data=data)# ------------------获取响应数据------------------
print(res.json())
print("响应头:",res.headers)# ------------------获取请求数据------------------
print("请求头:",res.request.headers)

案例2:json格式

想要指定请求参数的数据类型为json:

方法1:只需要加一个json参数,把data赋给json即可

--------------->>

案例1、案例2,我这边使用的是同一个测试网址,是因为该网址做了特殊处理,只要提交的请求参数正确,不论哪种请求的数据类型都可以兼容。

实际工作中,是否能够做到这样兼容,需要看公司的代码逻辑有没有这样处理

# 指定请求数据为json格式提交:方法1import requests
url = "http://域名/路径/xxx"
pulic_data = {"application": "app", "application_client_type": "weixin"}
data = {"accounts": "hailey", "pwd": "hailey123", "type": "username"}# 指定请求参数的数据类型为json,只需要加一个json参数,把data赋给json即可
res = requests.post(url,params=pulic_data,json=data) 
print("请求数据:",res.request.headers)
print("响应数据:",res.headers)

想要指定请求参数的数据类型为json:并且能不能请求参数的还是以data提交,只设置一下请求头为json呢?

方法2:

① 添加请求头设置

② data是字典类型,需要转换为json类型,不然打印响应信息会报错

------------>>

方式2处理起来稍微麻烦点,但是如果是封装的代码,就可以灵活处理,只设置请求头,可以在不同的地方使用不同的请求数据类型

具体代码如下:

import json
import requestsurl = "http://xxx.com/index.php?s=/api/user/login"
pulic_data = {"application": "app", "application_client_type": "weixin"}
data = {"accounts": "hailey", "pwd": "hailey123", "type": "username"}json_data = json.dumps(data)  # 将data字典转为json
header = {'Content-Type':'application/json;charset=utf-8'}  # 添加请求头设置
res = requests.post(url,params=pulic_data,headers=header,data=json_data)print("请求数据:", res.request.headers)
print("响应数据:", res.request.headers)

案例3:文件上传

基于flask框架实现的文件上传进行上传文件。
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架。
 # Flask框架安装pip install flask   # 安装命令
pip show flask      # 安装验证

flask的简单应用

定义一个Flask 应用程序对象 app = Flask ( __name__ )
静态路由: @app . route ( '/upload' )
指定允许的请求方法:@app.route('/login', methods=['GET', 'POST'])

上传文件接口

flask应用的完整代码(基于这段代码,才能完成下面的上传操作)

# flie name:uploadFile.pyfrom flask import Flask, request, jsonify
import os# 创建了一个名为 app 的 Flask 应用程序对象。
app = Flask(__name__)# 设置接口的路径,以及对应的请求方式
@app.route('/upload', methods=['POST'])
def upload():# 当没有image属性提示用户if 'image' not in request.files:data = {'msg': '当前未填写image参数','code': 400,}return jsonify(data)# 获取到当前图片请求中的文件file = request.files['image']print(file.filename)#  把对应的图片进行保存到当前的目录下的img目录(保存在当前服务器某个目录下)save_path = os.path.join('img', file.filename)file.save(save_path)data = {'msg': '上传成功','code': 200}return jsonify(data)if __name__ == '__main__':app.run()

先把代码运行,让服务启动(启动的是我们本地电脑的服务),不要手动停止

上传文件请求

# file name:p3_file.py
# 基于flask实现文件上传import requests# url:服务器 + 代码中定义的路径
url = "http://127.0.0.1:5000/upload"# 请求参数:image
file_data = {"image":open("python进阶.png","rb")}res = requests.post(url,files=file_data)
print("响应数据:",res.json())
print("响应的数据类型:",res.headers)

案例4:保持Session

如下代码,有两个接口:登录接口,查询信息接口,必须登录之后才可以查询用户信息。
当接口之间有上下游关联时,就需要 保持Session,即会话机制
Session也是一种鉴权,从头到尾,关闭就会失效
具体项目不同,有的只有token鉴权,没有Session鉴权

保持Session接口

由于手上没有可用的具有Session鉴权的项目,这里还是使用falks实现一个本地服务器,设置Session机制来演示效果;

以下是falks代码:

file name:loginApi.pyfrom flask import Flask, request, jsonify, session
import osapp = Flask(__name__)
app.secret_key = os.urandom(24)  # 设置一个密钥,用于加密 session 数据# 模拟用户信息,实际项目中需要替换为真实的用户信息
data = {"username": "hailey","password": "admin"}# 登录接口
@app.route('/login', methods=['POST'])
def login():data = request.get_json()username = data.get('username')password = data.get('password')if username in users and users[username] == password:# 登录成功,设置sessionsession['logged_in'] = Truereturn 'Login successful', 200else:return 'Login failed', 401# 查询信息接口,需要登录才能访问
@app.route('/get_info')
def get_info():if 'logged_in' in session and session['logged_in']:# 用户已登录,返回用户信息return 'User Info: OK'  # 返回用户信息else:# 用户未登录,返回未授权的状态码return 'Unauthorized', 401if __name__ == '__main__':app.run(debug=True)

还是先把代码运行,让服务启动(启动的是我们本地电脑的服务),不要手动停止

发送Session接口

错误示范

# file name:p4_session.pyimport requestsdata = {"username": "hailey","password": "admin"}#方法1:显示对应的未授权
response = requests.post("http://127.0.0.1:5000/login",json=data)
print("响应内容:",response.text)
response = requests.get("http://127.0.0.1:5000/get_info")
print(":",response.text)

正确姿势

在requests库中,如果需要进行session保持
1、需要实例化一个对象
2. 通过对应的对象去进行方法调用
import requestsdata = {"username": "hailey","password": "admin"}session = requests.Session()  #示例化对象
res = session.post("http://127.0.0.1:5000/login",json=data)
print("响应内容:",res.text)
res = session.get("http://127.0.0.1:5000/get_info")
print("get_info:",res.text)

3.5 josn概述补充

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于数据的序列化和传输。它基于JavaScript的语法,但可以被多种编程语言支持和解析。

下面是一个简单的JSON示例:

{
"name": "John",
"age": 30,
"isStudent": false,
"grades": [85, 92, 78],
"address": {
"street": "123 Main St",
"city": "New York"
}
}

JSON的优点

1. 简洁:相对于其他数据交换格式,JSON的语法简洁明了,易于阅读和编写。
2. 可读性好:JSON使用人类可读的文本格式,便于开发人员理解和调试。
3. 平台无关:JSON可以被多种编程语言支持和解析,使得不同平台之间的数据交换变得更加容易。
4. 支持复杂数据结构:JSON支持嵌套的对象和数组,可以表示复杂的数据结构。
在编程中,您可以使用相应编程语言提供的JSON库或工具来解析和生成JSON数据,以实现数据的序列化、传输和解析。

3.6 断言(Assert)

断言(Assertion)是一种在编程中常用的技术,用于检查代码中的条件是否满足,以确保程序的正确性。断言通常在程序中的关键位置或重要的检查点处使用,用于验证预期的条件是否为真。
断言的基本概念是
在代码中插入一条断言语句,该语句会在运行时进行条件判断:
        如果条件为假(False),则会触发断言错误,并中断程序的执行。
        如果条件为真(True),则程序会继续执行。

使用断言的目的

断言通常用于以下目的
1. 调试和验证 :断言可以用于验证程序的正确性和逻辑,帮助开发人员在调试过程中发现问题和错误。通过断言,可以检查程序中的假设是否成立,并在条件不满足时提前发现问题。
2. 防御性编程 :断言可以用于检查输入参数有效性或执行结果的正确性,以避免程序在非预期情况下继续行。
3. 测试和验证 :断言可以用于编写单元测试或验证代码的正确性,帮助捕捉潜在的错误和异常情况。

代码示例

# assert 表达式,表达式失败之后显示的字符串
import requestsurl = "http://xxxx.com/index.php?s=/api/user/login"
# 公共参数
pulic_data = {"application":"app","application_client_type":"weixin"}
# 请求参数:body
data = {"accounts":"hailey","pwd":"hailey123","type":"username"}# ------------------发送请求------------------
res = requests.post(url,params=pulic_data,data=data)# ------------------获取响应数据------------------
print(res.json())
response = res.json()# ------------------获取数据,进行断言处理------------------
# 断言成功
# assert "登录成功" == response["msg"],"期望结果是:{0},实际结果是:{1}".format("登录成功",response["msg"])# 断言失败
assert "登录失败" == response["msg"],"期望结果是:{0},实际结果是:{1}".format("登录失败",response["msg"])

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

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

相关文章

项目解决方案:多地医馆的高清视频监控接入汇聚联网

目 录 一、背景 二、建设目标及需求 1.建设目标 2.现状分析 3.需求分析 三、方案设计 1.设计依据 2.设计原则 3.方案设计 3.1 方案描述 3.2 组网说明 四、产品介绍 1.视频监控综合资源管理平台介绍 2.视频录像服务器和存储 2.1概述 2.2存储设计 …

51单片机流水灯

**led 介绍**LED是“Light Emitting Diode”的缩写,即发光二极管。它是一种半导体器件,能够将电能转化为可见光。LED灯通常由LED芯片、封装材料、铝基板和灯罩等部件组成。 **LED灯具有以下特点:** 节能:LED灯具有较高的光电转换…

oracle篇—19c新特性自动索引介绍

☘️博主介绍☘️: ✨又是一天没白过,我是奈斯,DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、Linux,也在积极的扩展IT方向的其他知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章,并且也会默默的点赞收藏加关注❣…

Go 知识slice

Go 知识slice 1. 什么是slice2. slice 基础2.1 定义 2.2 实现原理2.2.1 make 创建2.2.2 切片 创建 2.3 操作2.3.1 append 追加2.3.2 表达式切片2.3.3 扩展表达式2.3.4 扩容2.3.5 拷贝 3. 测试一下3.1 len && cap3.2 append && 扩容3.3 切片表达式 1. 什么是sli…

Vue2移动端项目使用$router.go(-1)不生效问题记录

目录 1、this.$router.go(-1) 改成 this.$router.back() 2、存储 from.path,使用 this.$router.push 3、hash模式中使用h5新增的onhashchange事件做hack处理 4、this.$router.go(-1) 之前添加一个 replace 方法 问题背景 : 在 Vue2 的一个移动端开发…

Docker安装与启动

Docker概述 Docker是一个快速交付应用、运行应用的技术: 可以将程序及其依赖、运行环境一起打包为一个镜像,可以迁移到任意Linux操作系统运行时利用沙箱机制形成隔离容器,各个应用互不干扰启动、移除都可以通过一行命令完成,方便…

AttributeError: module ‘numpy‘ has no attribute ‘float‘解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

YOLOv5改进系列(27)——添加SCConv注意力卷积(CVPR 2023|即插即用的高效卷积模块)

【YOLOv5改进系列】前期回顾: YOLOv5改进系列(0)——重要性能指标与训练结果评价及分析 YOLOv5改进系列(1)——添加SE注意力机制

【Docker】安装Nginx容器并部署前后端分离项目

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《Docker实战》。🎯🎯 &…

爬虫requests+综合练习

Day2 - 1.requests第一血_哔哩哔哩_bilibili requests作用:模拟浏览器发请求 requests流程:指定url -> 发起请求 -> 获取响应数据 -> 持续化存储 爬取搜狗首页的页面数据 import requests# 指定url url https://sogou.com # 发起请求 resp…

Three.JS教程1 环境搭建、场景与相机

Three.JS教程1 环境搭建、场景与相机 一、Three.JS简介二、环境搭建1. 开发准备2. 安装 three.js3. 新建文件index.htmlmain.js 4. 关于附加组件5. 启动 三、创建场景1. 场景的概念2. 相机的概念3. 相机的几个相关概念(1)视点(Position&#…

【redis13】集群前奏:sentinel模式

1.哨兵sentinel引入背景 我们现在来思考一个问题:如何实现服务的高可用。我们首先想到至少要满足两个要求:1.服务端能够实现主从自动切换;2.对于客户端来说,如果发生了主从切换,则能够自动连接到最新的master节点。 我…

S/MIME电子邮件证书申请指南

近年来,邮件安全问题日益突出,电子邮件成为诈骗、勒索软件攻击的重灾区。恶意邮件的占比屡创新高,邮件泄密事件更是比比皆是。在如此严峻的网络安全形势下,使用S/MIME电子邮件证书进行邮件收发是当今最佳的邮件安全解决方案之一。…

【PICO】【Unity】【VR】如何对打包后的PICO项目有效Debug

【背景】 PICO项目打包后再运行就看不到Console了。当然,会有各类专业的Debug工具。 有一类Debug的工具是Preview形式下展示Debug信息,但是发现Preview成功不见得打包也成功。 打包后也会有一些Debug工具,不过这里我给出自己的简单解决办法。 【解决方案】 Unity Console…

Java毕业设计-基于jsp+servlet的大学生学业规划咨询服务平台管理系统-第84期

获取源码资料,请移步从戎源码网:从戎源码网_专业的计算机毕业设计网站 项目介绍 基于jspservlet的大学生学业规划咨询服务平台管理系统:前端 jsp、jquery、ajax,后端 servlet、jdbc,角色分为管理员、学生&#xff1b…

Linux——进程等待

📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 文章目录 一、为什么要进程等待二、进程等待的方法1、wait方法2、waitpid方法 三、获取子进程status 一…

pxe高效批量网络装机 以及安装教程

系统装机的三种引导模式 1.pe 2光驱 3.网卡 打开本机桌面 可以看见背景图片 查看配置文件内容 文件时引导选项的功能 pxe原理: 先根据dhcp找到IP地址、和引导程序的地址,还提供客户机tftp地址,因为tftp是小文件,容量小&#…

【占用网络】FlashOcc:基于2D卷积的占用预测模型

前言 FlashOcc是一个它只需2D卷积就能实现“占用预测模型”,具有快速、节约内存、易部署的特点,偏工程方向的工作。 它首先采用2D卷积提取图形信息,生成BEV特征。然后通过通道到高度变换,将BEV特征提升到3D空间特征。 对于常规…

攻防世界——Shuffle

32bit打开 main函数F5 下班

SpringBoot+Email发送邮件

引言 邮件通知是现代应用中常见的一种通信方式,特别是在需要及时反馈、告警或重要事件通知的场景下。Spring Boot提供了简单而强大的邮件发送功能,使得实现邮件通知变得轻而易举。本文将研究如何在Spring Boot中使用JavaMailSender实现邮件发送&#xf…