flask框架基本使用

一、使用pycharm创建项目

1.创建项目

在这里插入图片描述

2.调整默认终端

在这里插入图片描述

3.打开虚拟终端

打开终端可以看出使用的是p1的虚拟机终端了

在这里插入图片描述

4.pyCharm小技巧

在flask种输入一个完整并且存在的函数名称或者类明, 然后 Alt + 回车,pycharm可以自动导包,不用在手动在代码头部导入包

二、安装flask

1.安装flask

(p1) E:\code\p1>pip install flask

2.查看安装包

pip list:查看所有的安装包
pip feeze 查看自己安装包

(p1) E:\code\p1>pip freeze
blinker==1.7.0
click==8.1.7             
colorama==0.4.6          
Flask==3.0.0       #这里安装的是3.0.0版本
importlib-metadata==7.0.1
itsdangerous==2.1.2      
Jinja2==3.1.2            
MarkupSafe==2.1.3        
Werkzeug==3.0.1          
zipp==3.17.0   

3.快速启动flask

创建app.py文件

from flask import Flask

#创建Flask对象
app = Flask(__name__)

# 路由 + 视图函数, 其中 / 就是用户访问的url,hello就是视图函数
@app.route('/')
def hello():
    #返回给浏览器的数据
    return 'hello'

if __name__ == "__main__":
    #启动flask
    app.run()

4.启动参数

app.run(debug=True,port=5000,host='0.0.0.0')

debug是开启调试模式,每次修改完代码之后不用重启flask

三、项目拆分(blue print)

因为flask所有的路由和视图函数都写在了app文件中,一旦逻辑复杂起来,函数多起来,阅读性就非常差,这就需要把项目差分开。这里就使用到了 “蓝图”。蓝图主要是是对 路由 进行了重新规划。
官方推荐了两种蓝图模式,这里只写一种。

1.视图基本原理

其原理就是把所有的视图函数文件、静态文件、模板文件都放在一个"包"中。然后将不通类型的视图函数 分开编写

2.目录结构

app.py #启动文件
apps   #这可是一个 自定义的python包
	__init__.py #包的初始化文件
	static      #存放静态文件的目录
	templates   #存放模板文件的目录
	views       #存放视图函数目录
		v1.py   #视图函数1
		v2.py   #视图函数2

3.编辑init文件

因为包的初始话文件,在其它文件导入的时候会自动执行,所有把创建flask的语句写在这里

from flask import  Flask

#导入两个蓝图
from .views.v1 import blue_login
from .views.v2 import blue_home


def create_app():
    app = Flask(__name__)

	#将app实例与两个蓝图绑定
    app.register_blueprint(blue_login)
    app.register_blueprint(blue_home)
    return app

4.编辑视图文件

编辑v1.py

from flask import  Blueprint

#创建一个蓝图,login为自定义的"蓝图"名称
blue_login = Blueprint("login",__name__)

@blue_login.route('/login')
def login():
    return '<h1>用户登录</h1>'

编辑v2.py

from flask import  Blueprint


blue_home = Blueprint("home",__name__)

@blue_home.route('/home')
def home():
    return '<h1>用户首页</h1>'

5.编辑app.py

from apps import create_app

app = create_app()


if __name__ == '__main__':
    app.run(debug=True,host="0.0.0.0")

6.访问

启动flask,分别访问这两个函数,就可以看到结果了

http://127.0.0.1:5000/home
http://127.0.0.1:5000/login

四、路由参数

有时候需要获取url中的参数,这时候就用到了 flask中的路由参数功能

from flask import Flask

app = Flask(__name__)

#username是一个string的变量,用户输入的url会赋值给username
@app.route('/<string:username>')
def login(username):
    return username


if __name__ == '__main__':
    app.run(debug=True,host="0.0.0.0")

flask支持的类型有以下几种:

string
int  #int 类型注意,flask是不能直接返回int类型的
float
path 
any
uuid

1.path

path类型,如果用户输入得到是多级url 比如: /xx/xx/xx/x/ 都会获取到

from flask import Flask

app = Flask(__name__)


@app.route('/<path:username>')
def login(username):
    return username


if __name__ == '__main__':
    app.run(debug=True,host="0.0.0.0")

用户请求多级目录 都会被获取到

http://127.0.0.1:5000/zhangsan/login/aaa

2.any

用户请求的路径必须在指定的值当中,如果不在就报错.当用户输入的是除zhangsan lisi以外的内容就会报错

@app.route('/<any(zhangsan,lisi):username>')
def login(username):
    return username

3.methods

限制用户使用请求方法

from flask import Flask

app = Flask(__name__)


@app.route('/',methods=['GET','POST'])
def login():
    return '首页'


if __name__ == '__main__':
    app.run(debug=True,host="0.0.0.0")

五、请求与响应

1.请求request

请求相关的属性

url  :完整的请求地址
base_url: 去掉get参数的url
host_url: 只有主机和端口号的url
path: 路由中的路径
method: 请求方法
remote_addr: 请求的客户端地址
args: get请求参数
form: post请求参数
files: 文件上传
headers 请求头
cookies: 请求中的cookie

打印参数

#这里要导入flask的request对象
from flask import Flask,request

app = Flask(__name__)


@app.route('/login',methods=['GET','POST'])
def login():
    print("url = {}".format(request.url))
    print("base_url = {}".format(request.base_url))
    print("host_url = {}".format(request.host_url))
    print("path = {}".format(request.path))
    print("method = {}".format(request.method))
    return '首页'


if __name__ == '__main__':
    app.run(debug=True,host="0.0.0.0")

在浏览器访问:

http://127.0.0.1:5000/login?user=zhangsan&password=123

结果如下

url = http://127.0.0.1:5000/login?user=zhangsan&password=123
base_url = http://127.0.0.1:5000/login
host_url = http://127.0.0.1:5000/
path = /login
method = GET

1.1 获取get请求参数

from flask import Flask,request

app = Flask(__name__)


@app.route('/login',methods=['GET','POST'])
def login():
	#这里只打印用户传递过来的参数
    print("args = {}".format(request.args))
    return '首页'


if __name__ == '__main__':
    app.run(debug=True,host="0.0.0.0")

浏览器访问

http://127.0.0.1:5000/login?user=zhangsan&password=123

打印结果如下:

args = ImmutableMultiDict([('user', 'zhangsan'), ('password', '123')])

ImmutableMultiDict这种类型叫做 “类对象”,获取类对象中的值方法有3种,如下:
三种方法的区别在于:
request.args[] 这种形式如果key不存在就会报错
request.args.get() 这种形式如果key不存在不会报错,会返回none,所以这种用的比较多
request.args.getlist() 如果args种 有重复的key,这种形式会将所有key都取出来,上边两种只会取第一个

from flask import Flask,request

app = Flask(__name__)


@app.route('/login',methods=['GET','POST'])
def login():
    print("args = {}".format(request.args))
    print(request.args['user'])
    print(request.args.get('user'))
    print(request.args.getlist('password'))
    return '首页'


if __name__ == '__main__':
    app.run(debug=True,host="0.0.0.0")

结果如下:

args = ImmutableMultiDict([('user', 'zhangsan'), ('password', '123')])
zhangsan
zhangsan
['123']

1.2 post请求

flask接受post请求使用的是 request.form。

from flask import Flask,request,jsonify

app = Flask(__name__)


@app.route('/login',methods=['GET','POST'])
def login():
    print('post请求={}'.format(request.form.get('user')))
    return '首页'


if __name__ == '__main__':
    app.run(debug=True,host="0.0.0.0")

使用postman 请求, post的数据需要使用"form-data"类型进行提交。 如果使用json格式进行提交,flask需要使用 request.json进行接收。

2.响应response

返回的数据一般有以下几种

2.1 字符串

return "字符串"

2.2 返回模板文件xx.html

这种使用的是前后端不分离的情况

#需要导入render_template
from flask import render_template

return render_template('index.html')

然后在templates目录下编写index.html

2.3 返回json数据

这种情况使用的是前后端分离的情况

return jsonify(python字典)

2.4 返回自定义response

def login():
    html = render_template('index.html',name="zhangsan")
    res = Response(html)
    return res

3.重定向

flask中重定向有两种用法
第一种:

from flask import Flask,redirect

app = Flask(__name__)


@app.route('/',methods=['GET','POST'])
def index():
    #如果用户访问根,直接跳转到 login路由
    return  redirect('/login')

@app.route('/login',methods=['GET','POST'])
def login():
    return "<h1>登录页面<h1>"


if __name__ == '__main__':
    app.run(debug=True,host="0.0.0.0")

第二种
url_for.以下这种方式也叫做 反向解析,通过函数名找url

res = url_for('蓝图名称.视图函数名称')
return redirect(res)

六、会话技术cookie

cookie是客户端的会话技术
cookie的作用:让服务器能够分判出 不同的http请求。应用场景一般用于登录。
产生cookie的过程:

1.用户携带用户名和密码进行登录
2.服务端验证用户名和密码,然后设置好cookie,和用户名和密码绑定,返回给浏览器
3.浏览器会自动保存cookie到本地
4.浏览器下次在请求的时,会自动带上cookie
5.取出cookie的值,判别哪个用户在访问,返回对应用户的数据

1.cookie相关参数

1.设置cookie
response.set_cookie(key,value[,max_age=None,exprise=None])

max_age: 整数,指定cookie的过期时间,单位为秒
expries: 整数,指定过期时间,可以指定一个具体日期时间
以上两个参数选择一个指定即可

2.获取cookie
request.cookies.get(key)

3.删除cookie
response.delete_cookie(key)

2.cookie实例

2.1 创建templates目录

此目录存放html文件,此目录下创建login.html,home.html

2.2 login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body>
    <form action="/login" method="post">
        <h1>登陆页面</h1>
        用户名:<input type="text" name="username" id=""><br>&emsp;码:<input type="password" name="password" id=""><br><br>
        <button type="submit">提交按钮</button>
    </form>

</body>
</html>

2.3 home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>home</title>
</head>
<body>
    <h1>Home页面</h1>
</body>
</html>

2.4 main.py

解释:max

from flask import Flask,render_template,request,Response,redirect

app = Flask(__name__)

@app.route("/")
@app.route('/login',methods=["GET","POST"])
def login():
    if request.method == "GET":
        return  render_template("login.html")
    elif request.method == "POST":
        username = request.form.get("username")
        passworwd = request.form.get("password")

        if username == "admin" and passworwd == "admin":
            getCookie = request.cookies.get("testcookie")
            if getCookie:
                return redirect("/home")
            else:
                res = redirect("/home")
                res.set_cookie("testcookie","2024",max_age=10)
                return res

        else:
            return "用户名或者密码错误"

@app.route("/home")
def home():
    getCookie = request.cookies.get("testcookie")
    if getCookie == "2024":
        return render_template("home.html")
    else:
        return redirect("/login")



if __name__ == "__main__":
    app.run(debug=True,host="0.0.0.0")

解释: cookie的过期时间为10秒,过期后,浏览器会自动删除cookie

六、会话技术-session

session是服务器端的会话技术,依赖于cookie
特点:
服务端的会话技术
所有数据存在服务器中
默认存储在内存中
存储结果也是key-value的形式
session 是离不开cookie

flask中的seesion是全局对象

1.常用操作

设置session 
	session['key'] = 'value'

获取session
	session.get(key,default=NOne)

删除session
	session.pop(key)删除某一值
    session.clear() 清楚所有

2.session和cookie的区别

cookie:
	1.在浏览器存储
	2.安全性较低
	3.可以减轻服务器压力
session:
	1.在服务器存储
	2.安全性高
	3.对服务器要求较高
	4.依赖cookie

3.实例

3.1 增加退出功能

在home.html中增加 退出

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>home</title>
</head>
<body>
    <h1>Home页面</h1>
    <form action="logout" method="post">
        <button type="submit">注销</button>
    </form>

</body>
</html>

3.2 main.py

from flask import Flask,render_template,request,Response,redirect,session
import datetime



app = Flask(__name__)
#设置一个安全的密钥,否则无法成功返回session
app.secret_key = "abc123"

#为了测试设置session的过期时间为3秒,session过期后不会自动删除sessIon
app.permanent_session_lifetime = datetime.timedelta(seconds=3)



@app.route("/")
@app.route('/login',methods=["GET","POST"])
def login():
    if request.method == "GET":
        return  render_template("login.html")

    elif request.method == "POST":
        username = request.form.get("username")
        passworwd = request.form.get("password")

        if username == "admin" and passworwd == "admin":
            getCookie = session.get("testcookie")
            if getCookie:
                return redirect("/home")
            else:
                res = redirect("/home")
                session["testcookie"] = "2024"
                return res

        else:
            return "用户名或者密码错误"

@app.route("/home")
def home():
    getCookie = session.get("testcookie")
    if getCookie == "2024":
        return render_template("home.html")
    else:
        return redirect("/login")

@app.route("/logout",methods=["POST"])
def logout():
    session.pop('testcookie')
    return  redirect("/login")


if __name__ == "__main__":
    app.run(debug=True,host="0.0.0.0")

七、文件上传request.files

1.模板文件

[root@node-2 templates]# cat index.html 
<h1>
	<form action="/upload" method="post" enctype="multipart/form-data">
	
   		#这里的 name的值决定了 flask 获取上传文件的key  	
    	<input type="file" id="fileInput" name="file">
    	<br><br>
    	<input type="submit" value="提交">
	</form>
</h1>

2.main.py

from  flask  import Flask,render_template,request

app = Flask(__name__)

@app.route("/")
def index():
	return render_template("index.html")

@app.route("/upload",methods=["GET","POST"])
def upload():
	print(request.files)
	print(request.files.get('file'))
	print(request.files.get('file').filename)
	return "upload OK!!!	

if __name__ == "__main__":
        app.run(debug=True,host='0.0.0.0')

上传一张图片,查看日志

打印结果如下:

ImmutableMultiDict([('file', <FileStorage: '1.jpeg' ('image/jpeg')>)])
<FileStorage: '1.jpeg' ('image/jpeg')>
1.jpeg

2.1 查看上传对象

request.files的值为

ImmutableMultiDict([('file', <FileStorage: '2.jpeg' ('image/jpeg')>)])

这里的file 就是 html中 input 中的name的值

2.2 获取存储对象

request.file.get(‘file’) 的值为:

<FileStorage: '2.jpeg' ('image/jpeg')>

这个值就是要存储的对象

2.3 获取上传文件名称

request.file.get(‘file’).filename 的值

1.jpeg

3.保存上传文件

from  flask  import Flask,render_template,request

app = Flask(__name__)

@app.route("/")
def index():
        return render_template("index.html")

@app.route("/upload",methods=["GET","POST"])
def upload():
        save_url = "/root/python"
        files = request.files.get('file')
        
        if files:
                file_name = files.filename
                files.save("{}/{}".format(save_url,file_name))
                return "upload OK!!!"
        else:
                return "上传文件不能为空!"
                
                
if __name__ == "__main__":
        app.run(debug=True,host='0.0.0.0')

八、模板

Flask中使用Jinja2模板引擎
Jinja2是由Flask作者开发。
模板优势:
速度快,被广泛应用
HTML设计和后端python分离
减少python复杂度
非常灵活,快速和安全
提供了控制,继承等高级功能

小技巧:

在pycharm中写html 输入任意标签 按tab键自动补齐标签。

1.模板语法

模板语法主要有两种:

变量 和 标签

1.1.模板中的变量

语法: {{ 变量名 }}
视图传递给模板的数据
变量如果不存在,默认忽略

1.2.模板中的标签

语法: {% 标签 %}|
这个标签可以是 控制逻辑,外部表表达式,创建变量、宏定义

2.简单实例

2.1 变量传递

视图函数中传递变量

return  render_template('login.html',username=”zhangsan“)

html中引入变量

<p>姓名: {{ username }}</p>

2.2 复杂传递

视图中定义变量,并返回

def login():
    data = {
        "user": "zhangsan",
        "age": 20,
        "likes": ["乒乓球","游泳","听音乐"]
    }
    return  render_template('login.html',**data)

html中引入传入的data的值

<body>
  <h1>登录首页</h1>
  <p>姓名: {{ user }}</p>
  <p>年龄: {{ age }}</p>
  <p>爱好: {{ likes[0] }}</p>

</body>

2.3 if判断

  <p>姓名: {{ user }}</p>
  {% if age > 18 %}
    <p>年龄:成年人</p>
  {% else %}
    <p>年龄:未成年</p>
  {% endif %}
  <p>爱好: {{ likes[0] }}</p>

2.4 for循环

其中 loop.index0 写法是固定的。

<body>
     <h1>爱好</h1>
    {% for i in likes %}
        <h2>{{ i }}</h2>
        索引: {{ loop.index0 }}
    {% endfor %}
</body>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue面试之组件通信的方式总结(下篇)

Vue面试之组件通信的方式总结 $refprovide&injectprovideinject EventBus事件总线vuex 最近在整理一些前端面试中经常被问到的问题&#xff0c;分为vue相关、react相关、js相关、react相关等等专题&#xff0c;可持续关注后续内容&#xff0c;会不断进行整理~ 在Vue框架中&…

利用Wireshark分析IP协议

实验.利用Wireshark分析IP协议 一&#xff0e;实验目的 1.掌握Wireshark软件简单的过滤语法 2.掌握IP数据报的组成格式 3.掌握IP分片的计算方法 4.学会利用Wireshark抓包分析IP协议 二&#xff0e;实验环境 1.Wireshark软件 2.Windows 计算机 三&#xff0e;实验预备知识 1.IP…

vcruntime140_1.dll无法继续执行代码怎么办?6个修复方法分享

找不到vcruntime1401.dll”。这个错误提示通常意味着我们的计算机缺少了一个重要的动态链接库文件。本文将介绍vcruntime1401.dll是什么文件、它的作用以及当电脑丢失该文件时可能产生的影响&#xff0c;并提供6个解决方法来解决这个问题。 一、vcruntime1401.dll是什么文件&a…

Pytorch基础:数据读取与预处理——调用PyTorch官方数据集

数据读取与预处理——调用PyTorch官方数据集 1. 从网络端下载 FashionMNIST 数据集到本地2. 数据集可视化 1. 从网络端下载 FashionMNIST 数据集到本地 (base) PS C:\Users\孙明阳> conda activate yang (yang) PS C:\Users\孙明阳> python Python 3.11.5 | packaged by…

RocketMQ源码阅读-Producer发消息

RocketMQ源码阅读-Producer发消息 1. 从单元测试入手2. 启动过程3. 同步消息发送过程4. 异步消息发送过程5. 小结 Producer是消息的生产者。 Producer和Consummer对Rocket来说都是Client&#xff0c;Server是NameServer。 客户端在源码中是一个单独的Model&#xff0c;目录为ro…

Nginx——基础配置

和大多数软件一样&#xff0c;Nginx也有自己的配置文件&#xff0c;但它又有很多与众不同的地方&#xff0c;本帖就来揭开Nginx基础配置的面纱。 1、Nginx指令和指令块 了解指令和指令块有助于大家了解配置的上下文&#xff0c;下面是一个配置模板示例&#xff1a; 在这个配…

JavaScript删除数组中指定元素的5种方法

文章目录 目录 文章目录 前言 一、数组是什么&#xff1f; 二、讲解数组 总结 前言 在JavaScript开发中&#xff0c;处理数组是一项非常常见的任务。有时候我们需要从数组中删除特定的元素&#xff0c;以便对数组进行进一步操作或者满足特定的需求。幸运的是&#xff0c;JavaS…

《BackTrader量化交易图解》第10章:Trade 交易操作

文章目录 10 Trade 交易操作10.1 量化回测分析流程10.2 Cerebro 类模块10.3 案例&#xff1a;Trade 交易10.4 实盘交易机器隐性规则10.5 Stake 交易数额和 Trade 交易执行价格 10 Trade 交易操作 10.1 量化回测分析流程 从本章开始讲解 BackTrader 的实盘操作。前面的章节讲过…

redis系列:01 数据类型及操作

redis的数据类型有哪些 string,list,set,sorted_set,hash 操作 sting: set name maliao get name exists name expire name 5 ttl name del name setex name 10 maliao 设置key和过期时间 setnx name maliao 当key不存在时才添加list&#xff1a; lpush letter a lpush le…

二极管选型怎么选?常用参数要熟练~

同学们大家好&#xff0c;今天我们继续学习杨欣的《电子设计从零开始》&#xff0c;这本书从基本原理出发&#xff0c;知识点遍及无线电通讯、仪器设计、三极管电路、集成电路、传感器、数字电路基础、单片机及应用实例&#xff0c;可以说是全面系统地介绍了电子设计所需的知识…

【LeetCode】206. 反转链表(简单)——代码随想录算法训练营Day01

题目链接&#xff1a;206. 反转链表 题目描述 206. 反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例 2&#xff1a; 输入&#xff1…

公司寄快递教程

公司寄快递用哪个更划算&#xff1f;这个问题有最优解吗&#xff1f;恐怕没有......很简单&#xff0c;回答这个问题之前&#xff0c;我们先来看看公司寄快递的背景。 一、大背景 所谓的大背景是由国内快递行业的发展现状所决定的。众所周知&#xff0c;这十年来&#xff0c;国…

Centos安装Datax

Centos7安装DataX 一、DataX简介二、DataX的数据源支持三、安装DataX1、下载DataX2、解压3、检验是否安装成功4、使用 四、实践案例1、环境信息2、编写同步的配置文件(user_info.json)3、执行同步4、验证同步结果 一、DataX简介 DataX 是阿里云 DataWorks数据集成 的开源版本&a…

Minitab的单因子方差分析的结果

单因子方差分析概述 当有一个类别因子和一个连续响应并且想要确定两个或多个组的总体均值是否存在差异时&#xff0c;可使用 单因子方差分析。如果经检验&#xff0c;发现至少有一组存在差异&#xff0c;请使用单因子方差分析中的比较对话框来标识存在显著差异的组对。 例如&…

C++ 之LeetCode刷题记录(九)

&#x1f604;&#x1f60a;&#x1f606;&#x1f603;&#x1f604;&#x1f60a;&#x1f606;&#x1f603; 开始cpp刷题之旅&#xff0c;多学多练&#xff0c;尽力而为。 先易后难&#xff0c;先刷简单的。 58. 最后一个单词的长度 给你一个字符串 s&#xff0c;由若干…

代码随想录第第五十七天—回文子串,最长回文子序列

leetcode 647. 回文子串 题目链接&#xff1a;回文子串 版本一&#xff1a;动态规划 dp数组及下标的含义 dp[i][j]&#xff1a;区间范围[i, j] &#xff08;左闭右闭&#xff09;的子串是否是回文子串&#xff0c;如果是dp[i][j]为true&#xff0c;否则为false。确定递推公式…

Notepad++安装步骤

Notepad是一款文本编辑工具&#xff0c;支持27种编程语言&#xff0c;通吃C,C ,Java ,C#, XML, HTML, PHP,JS 等&#xff0c;该软件拥有完整的中文化接口及支持多国语言编写的功能&#xff0c;不仅可以用来制作一般的纯文字说明文件&#xff0c;还非常适合编写计算机程序代码&a…

大数据StarRocks(五) :数据类型

StarRocks 支持数据类型&#xff1a;数值类型、字符串类型、日期类型、半结构化类型、其他类型。您在建表时可以指定以下类型的列&#xff0c;向表中导入该类型的数据并查询数据。 5.1 数值类型 SMALLINT2 字节有符号整数&#xff0c;范围 [-32768, 32767] INT4 字节有符号整…

leetcode 动态规划(爬楼梯、零钱兑换、完全平方数)

70. 爬楼梯&#xff08;进阶版&#xff09; 卡码网&#xff1a;57. 爬楼梯(opens new window) 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬至多m (1 < m < n)个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 注意&#xff1a;给定 n 是一个正…

RedisTemplate使用zadd报错java.lang.StackOverflowError

代码当中使用RedisTemplate操作String、List都是正常的&#xff0c;但是操作zadd就会报错&#xff0c;有人说是这两个依赖的版本不一致的问题&#xff0c;但是项目中还有其他地方要用到&#xff0c;所以改版本号行不通&#xff0c; <dependency><groupId>org.redis…