当前位置: 首页 > news >正文

JWT+Redis 实现接口 Token 校验

1、业务逻辑

有一些接口,需要用户登录以后才能访问,用户没有登录则无法访问。 因此,对于一些限制用户访问的接口,可以在请求头中增加一个校验参数,用于判断接口对应的用户是否登录。 而对于一些不需要登录即可访问的接口,则需要进行放行操作。

2、代码逻辑
  1. 用户访问登录接口,校验通过则生成token标识,并且将token存入缓存;
  2. 请求其它接口时,在请求头中添加token参数;
  3. 后台收到请求后,根据接口路径的匹配程度决定是否对此次请求进行token校验;
  4. 需要校验的请求,会在到达controller层之前被拦截,进行对应的逻辑判断和校验;
  5. 校验通过的请求会顺利到达controller层,不通过则立即将校验失败的结果返回。
3、代码具体实现
(1)生成token

采用JWT方式生成token,登录成功后将用户的部分信息加密后生成token,并且保存到redis中。

<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.14.0</version>
</dependency>
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.mashibing.internalcommon.dto.TokenResult;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JWTUtils {// JWT签名private static final String SIGN = "i_am_study"; // 用户信息private static final String JWT_KEY_PHONE = "phone";private static final String JWT_KEY_IDENTITY = "identity";private static final String TOKEN_TYPE = "tokenType";private static final String TOKEN_TIME = "tokenTime";/*** 根据用户信息生成JWT* @param passengerPhone 手机号* @param identity 用户身份类型标识* @param tokenType  token类型标识* @return*/public static String generatorToken(String passengerPhone, String identity, String tokenType){Map<String, String> map = new HashMap<>();map.put(JWT_KEY_PHONE, passengerPhone);map.put(JWT_KEY_IDENTITY, identity);map.put(TOKEN_TYPE, tokenType);map.put(TOKEN_TIME, Calendar.getInstance().getTime().toString());// 整合 mapJWTCreator.Builder builder = JWT.create();map.forEach((k, v) -> {builder.withClaim(k, v);});String sign = builder.sign(Algorithm.HMAC256(SIGN));return sign;}/*** 解析JWT获取用户信息* @param token JWT类型字符串* @return*/public static TokenResult paseToken(String token) {DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);String phone = verify.getClaim(JWT_KEY_PHONE).asString();String identity = verify.getClaim(JWT_KEY_IDENTITY).asString();TokenResult tokenResult = new TokenResult();tokenResult.setIdentity(identity);tokenResult.setPhone(phone);return tokenResult;}/*** 验证JWT合法性 * @param token JWT字符串* @return*/public static TokenResult checkToken(String token) {TokenResult tokenResult = null;try {tokenResult = JWTUtils.paseToken(token);} catch (Exception e) {}return tokenResult;}}
(2)Redis获取token

用户登录采用的是手机号+验证码的方式,根据手机号从Redis中拿到验证码,并与用户输入的验证码进行比较,如果相等则返回双token。

/*** 用户根据手机号和验证码登录 * @param driverPhone  手机号 * @param verificationCode  验证码 * @return*/
public ResponseResult checkVerficationCode(String driverPhone, String verificationCode) {// 1.根据手机号获取验证码String key = RedisPrefixUtils.generatorKeyByPhone(driverPhone, IdentityConstant.DRIVER_IDENTITY);String codeRedis = redisTemplate.opsForValue().get(key);System.out.println("从redis获取的验证码是: " + codeRedis);// 2.校验验证码if (StringUtil.isNullOrEmpty(codeRedis)) {return ResponseResult.fail(CommonStatusEnum.VERIFICATON_CODE_EXPIRE.getCode(),CommonStatusEnum.VERIFICATON_CODE_EXPIRE.getValue());}if (!verificationCode.trim().equals(codeRedis)){return ResponseResult.fail(CommonStatusEnum.VERIFICATION_CODE_ERRO.getCode(),CommonStatusEnum.VERIFICATION_CODE_ERRO.getValue());}// 4.生成token返回String accessToken = JWTUtils.generatorToken(driverPhone, IdentityConstant.DRIVER_IDENTITY, TokenConstant.ACCESS_TOKEN_TYPE);String refreshToken = JWTUtils.generatorToken(driverPhone, IdentityConstant.DRIVER_IDENTITY, TokenConstant.REFRESH_TOKEN_TYPE);// 生成keyString accessTokenKey = RedisPrefixUtils.generatorTokenKey(driverPhone, IdentityConstant.DRIVER_IDENTITY, TokenConstant.ACCESS_TOKEN_TYPE);String refreshTokenKey = RedisPrefixUtils.generatorTokenKey(driverPhone, IdentityConstant.DRIVER_IDENTITY, TokenConstant.REFRESH_TOKEN_TYPE);// 存到redisredisTemplate.opsForValue().set(accessTokenKey, accessToken,  30, TimeUnit.DAYS);redisTemplate.opsForValue().set(refreshTokenKey, refreshToken,  31, TimeUnit.DAYS);// 结果返回TokenResponse tokenResponse = new TokenResponse();tokenResponse.setAcccessToken(accessToken);tokenResponse.setRefreshToken(refreshToken);return ResponseResult.success(tokenResponse);
}
(3)校验token

重写HandlerInterceptor接口的preHandle方法,拿到token进行判断 。 只需要从请求头中拿到token,然后根据token拿到对应的存储到redis中的key,根据key查询redis判断是否存在对应token,存在则放行,不存在则不放行。

  • 在拦截器中编写token校验逻辑
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;public class JwtInterceptor implements HandlerInterceptor {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");boolean result = true;String resultString = "";// 解析token,校验token的准确性 TokenResult tokenResult = JWTUtils.checkToken(token);if(tokenResult == null){resultString = "token valid";result = false;}else {// 解析token,获取token中携带的参数信息 tokenResult = JWTUtils.paseToken(token);// 判断redis中是否存在对应token,即判断token是否到期 String tokenKey = RedisPrefixUtils.generatorTokenKey(tokenResult.getPhone(), IdentityConstant.DRIVER_IDENTITY, TokenConstant.ACCESS_TOKEN_TYPE);String redisToken = stringRedisTemplate.opsForValue().get(tokenKey);if (redisToken==null ||  !redisToken.trim().equals(token)){resultString = "token valid";result = false;}}if (!result) {// 告知前端PrintWriter out = response.getWriter();out.print(JSONObject.fromObject(ResponseResult.fail(resultString)).toString());}return result;}
}
  • 将重写之后的拦截器加入到spring容器中
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
// 将拦截器注册
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {@Beanpublic JwtInterceptor jwtInterceptor(){return new JwtInterceptor();}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(jwtInterceptor())// 拦截的路径.addPathPatterns("/**")// 不拦截的路径.excludePathPatterns("/noauth","/error","/verification-code","/verification-code-check");}}

相关文章:

JWT+Redis 实现接口 Token 校验

1、业务逻辑 有一些接口&#xff0c;需要用户登录以后才能访问&#xff0c;用户没有登录则无法访问。 因此&#xff0c;对于一些限制用户访问的接口&#xff0c;可以在请求头中增加一个校验参数&#xff0c;用于判断接口对应的用户是否登录。 而对于一些不需要登录即可访问的接…...

C语言 linux文件操作(二)

文章目录 一、获取文件长度二、追加写入三、覆盖写入四、文件创建函数creat 一、获取文件长度 通过lseek函数&#xff0c;除了操作定位文件指针&#xff0c;还可以获取到文件大小&#xff0c;注意这里是文件大小&#xff0c;单位是字节。例如在file1文件中事先写入"你好世…...

机器学习分类

1. 监督学习 监督学习指的是人们给机器一大堆标记好的数据&#xff0c;比如&#xff1a; 一大堆照片&#xff0c;标记出哪些是猫的照片&#xff0c;哪些是狗的照片 让机器自己学习归纳出算法或模型 使用该算法或模型判断出其他没有标记的照片是否是猫或狗 上述流程如下图所…...

CSS之元素转换

我想大家在写代码时有一个疑问&#xff0c;块级元素可以转换成其他元素吗&#xff1f; 让我为大家介绍一下元素转换 1.display:block(转换成块元素) display&#xff1a;block可以把我们的行内元素或者行内块元素转换成块元素 接下来让我为大家演示一下&#xff1a; <!DO…...

自激振荡电路笔记 电弧打火机

三极管相关 三极管的形象描述 二极管 简单求解&#xff08;理想&#xff09; 优先导通&#xff08;理想&#xff09; 恒压降 稳压管&#xff08;二极管plus&#xff09; 基础工作模块 理想稳压管的工作特性 晶体管之三极管(“两个二极管的组合” ) 电弧打火机电路 1.闭合开…...

Linux su 命令

Linux su&#xff08;英文全拼&#xff1a;switch user&#xff09;命令用于变更为其他使用者的身份&#xff0c;除 root 外&#xff0c;需要键入该使用者的密码。 使用权限&#xff1a;所有使用者。 语法 su [-fmp] [-c command] [-s shell] [--help] [--version] [-] [USE…...

论文阅读: AAAI 2022行人重识别方向论文-PFD_Net

本篇博客用于记录一篇行人重识别方向的论文所提出的优化方法《Pose-Guided Feature Disentangling for Occluded Person Re-identification Based on Transformer》&#xff0c;论文中提出的PDF_Net模型的backbone是采用《TransReID: Transformer-based Object Re-Identificati…...

蓝牙物联网灯控设计方案

蓝牙技术是当前应用最广泛的无线通信技术之一&#xff0c;工作在全球通用的 2.4GHZ 的ISM 频段。蓝牙的工作距离约为 100 米&#xff0c;具有一定的穿透性&#xff0c;没有方向限制。具有低成本、抗干扰能力强、传输质量高、低功耗等特点。蓝牙技术组网比较简单&#xff0c;无需…...

Codeforces Round 900 (Div. 3)(A-F)

比赛链接 : Dashboard - Codeforces Round 900 (Div. 3) - Codeforces A. How Much Does Daytona Cost? 题面 : 思路 : 在序列中只要找到k&#xff0c;就返回true ; 代码 : #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)…...

vue大屏-列表自动滚动vue-seamless-scroll

vue大屏-列表自动滚动vue-seamless-scroll vue-seamless-scroll的官方文档地址&#xff1a;https://chenxuan0000.github.io/vue-seamless-scroll/zh/guide/ 具体效果可到官方文档那里查看。 1、下载依赖 npm install vue-seamless-scroll --save2、使用例子 <template…...

easyx的窗口函数

文章目录 前言一、EasyX的颜色二、EasyX的坐标和设备1&#xff0c;EasyX的坐标2&#xff0c;EasyX的设备 三、窗口函数1&#xff0c;初始化窗口函数2&#xff0c;关闭绘图窗口3&#xff0c;设置窗口背景板颜色4&#xff0c;清空绘图设备 前言 easyx是针对c的图形库&#xff0c;…...

【记录】开始学习网络安全

本文持续更新学习进度 背景 在私企干了5年虚拟化、云原生相关的运维&#xff0c;学到了很多&#xff0c;但不成体系。老板是清华毕业法国留学在德勤干过&#xff0c;最后回国创业的野路子。我工作是为了更好的生活&#xff0c;我挺担心老板因为家庭变故或者炒个原油宝&#x…...

【Java EE初阶三 】线程的状态与安全(下)

3. 线程安全 线程安全&#xff1a;某个代码&#xff0c;不管它是单个线程执行&#xff0c;还是多个线程执行&#xff0c;都不会产生bug&#xff0c;这个情况就成为“线程安全”。 线程不安全&#xff1a;某个代码&#xff0c;它单个线程执行&#xff0c;不会产生bug&#xff0c…...

MD5算法

一、引言 MD5&#xff08;Message-Digest Algorithm 5&#xff09;是一种广泛应用的密码散列算法&#xff0c;由Ronald L. Rivest于1991年提出。MD5算法主要用于对任意长度的消息进行加密&#xff0c;将消息压缩成固定长度的摘要&#xff08;通常为128位&#xff09;。在密码学…...

Postman使用

Postman使用 Pre-request Script 参考&#xff1a; Scripting in Postman 可以请求、集合或文件夹中添加Pre-request Script&#xff0c;在请求运行之前执行JavaScript 如设置变量值、参数、Header和正文数据&#xff0c;也可以使用Pre-request Script来调试代码&#xff0…...

【python 的各种模块】(8) 在python使用matplotlib和wordcloud库来画wordcloud词云图

目录 目标&#xff1a;用python画出&#xff0c;网上流行的wordcloud词云图 1 准备工作 1.1环境准备 1.1.1安装步骤 1.2 资源准备 1.2.1 文本文件内容如下 1.2.2 图片资源 2 代码测试 2.1 第一版代码和效果 2.1.1 代码和效果 2.1.2 一般plt里解决中文乱码问题 2.1…...

MFC随对话框大小改变同时改变控件大小

先看一下效果; 初始; 窗口变大,控件也变大; 二个也可以; 窗口变大,控件变大; 默认生成的对话框没有WM_SIZE消息的处理程序;打开类向导,选中WM_SIZE消息,对CxxxDlg类添加该消息的处理程序;默认生成的函数名是OnSize; 添加了以后代码中会有三处变化; 在对话框类的…...

MK米客方德品牌 SD NAND在对讲机领域的引领作用

SD NAND在对讲机上的应用 SD NAND在对讲机上广泛应用&#xff0c;为其提供了高效可靠的存储解决方案。 这种存储技术不仅能容纳大量语音和数据文件&#xff0c;而且具有高速读取的特点&#xff0c;保障了实时通信的质量。SD NAND还注重安全性&#xff0c;通过数据加密和访问控…...

软件测试/测试开发丨Python 封装 学习笔记

封装的概念 封装&#xff08;Encapsulation&#xff09; 隐藏&#xff1a;属性和实现细节&#xff0c;不允许外部直接访问暴露&#xff1a;公开方法&#xff0c;实现对内部信息的操作和访问 封装的作用 限制安全的访问和操作&#xff0c;提高数据安全性可进行数据检查&#x…...

Vue: 事件修饰符, 键盘事件, 鼠标事件,计算属性

目录 事件修饰符 阻止默认事件 阻止冒泡 允许触发一次 捕获模式 self passive 键盘事件 keyup & keydown 按键别名 注意tab 注意系统按键 自定义按键 鼠标事件 简介 鼠标焦点事件 计算属性 差值语法实现 methods实现 computed实现 get() set() 总…...

【ROS2】MOMO的鱼香ROS2(四)ROS2入门篇——ROS2节点通信之话题与服务

ROS2节点通信之话题与服务点 引言1 理解从通信开始1.1 TCP&#xff08;传输控制协议&#xff09;1.2 UDP&#xff08;用户数据报协议&#xff09;1.3 基于共享内存的IPC方式 2 ROS2话题2.1 ROS2话题指令2.2 话题之RCLPY实现2.2.1 编写发布者2.2 2 编写订阅者2.2.3 运行测试 3 R…...

2022年山东省职业院校技能大赛高职组云计算赛项试卷第三场-公有云

2022年山东省职业院校技能大赛高职组云计算赛项试卷 目录 2022年职业院校技能大赛高职组云计算赛项试卷 【赛程名称】云计算赛项第三场-公有云 【任务1】公有云服务搭建[10分] 【适用平台】华为云 【题目1】私有网络管理[0.5分] 【题目2】云实例管理[0.5分] 【题目3】数…...

现代 NLP:详细概述,第 1 部分:transformer

阿比吉特罗伊 一、说明...

记一次Mac端mysql重置密码

在执行mysql命令的时候&#xff0c;报如下的错误&#xff0c;表示不支持mysql命令&#xff1a; zsh: command not found: mysql 1. 先查看mysql服务是否存在 在系统偏好设置中查看&#xff1a; 2. 发现mysql服务已经在运行&#xff0c;可能因为/usr/local/bin目录下缺失mysq…...

【开题报告】基于java的流浪之家动物领养网站的设计与开发

1.选题背景 流浪之家动物领养网站的设计与开发背景主要源于对流浪动物保护和宠物领养问题的关注。随着城市化进程加快&#xff0c;越来越多的流浪动物出现在城市中&#xff0c;它们面临着食物、住所和医疗资源的缺乏。同时&#xff0c;许多爱心人士希望能够给流浪动物一个温暖…...

训狗技术从初级到高级,专业有效的训狗训犬教程

一、教程描述 现在大部分人家里都会养些宠物&#xff0c;比如狗狗&#xff0c;虽然狗狗的一些行为习惯跟遗传有关&#xff0c;但是主人后天的影响也会给狗狗带来改变&#xff0c;本套教程教你纠正狗狗的不良行为&#xff0c;可以让你与狗愉快地玩耍。本套训狗教程&#xff0c;…...

如何让机器人具备实时、多模态的触觉感知能力?

人类能够直观地感知和理解复杂的触觉信息&#xff0c;是因为分布在指尖皮肤的皮肤感受器同时接收到不同的触觉刺激&#xff0c;并将触觉信号立即传输到大脑。尽管许多研究小组试图模仿人类皮肤的结构和功能&#xff0c;但在一个系统内实现类似人类的触觉感知过程仍然是一个挑战…...

datax

DataX DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台&#xff0c;实现包括 MySQL、SQL Server、Oracle、PostgreSQL、HDFS、Hive、HBase、OTS、ODPS 等各种异构数据源之间高效的数据同步功能。 https://github.com/alibaba/DataX Features DataX本身作为数据同…...

【Java】SpringBoot快速整合WebSocket实现客户端服务端相互推送信息

目录 什么是webSocket&#xff1f; webSocket可以用来做什么? WebSocket操作类 一&#xff1a;测试客户端向服务端推送消息 1.启动SpringBoot项目 2.打开网站 3.进行测试消息推送 4.后端进行查看测试结果 二&#xff1a;测试服务端向客户端推送消息 1.接口代码 2.使…...

C语言 linux文件操作(一)

文章目录 一、linux文件权限1.1文件描述符1.2文件描述符的范围和默认值1.3打开文件和文件描述符1.4标准文件描述符1.5文件描述符的重定向和关闭1.6I/O 操作1.7使用文件描述符进行进程通信1.8资源限制 二、C语言文件读写2.1open 函数2.2 flags参数详解2.3 lseek 函数 一、linux文…...

007、控制流

先看下本篇学习内容&#xff1a; 通过条件来执行 或 重复执行某些代码 是大部分编程语言的基础组成部分。在Rust中用来控制程序执行流的结构主要就是 if表达式 与 循环表达式。 1. if表达式 if表达式允许我们根据条件执行不同的代码分支。我们提供一个条件&#xff0c;并且做出…...

将学习自动化测试时的医药管理信息系统项目用idea运行

将学习自动化测试时的医药管理信息系统项目用idea运行 背景 学习自动化测试的时候老师的运行方式是把医药管理信息系统项目打包成war包后再放到tomcat的webapp中去运行&#xff0c;于是我想着用idea运行会方便点&#xff0c;现在记录下步骤方便以后查找最开始没有查阅资料&am…...

k8s 的YAML文件详解

一、yaml文件简介 Kubernetes只支持YAML和JSON格式创建资源对象&#xff0c;JSON格式用于接口之间消息的传递&#xff0c;适用于开发&#xff1b;YAML格式用于配置和管理&#xff0c;适用于云平台管理&#xff0c;YAML是一种简洁的非标记性语言。 1&#xff09;yaml的语法规则&…...

【Pytorch】Pytorch或者CUDA版本不符合问题解决与分析

NVIDIA CUDA Toolkit Release Notes Package installation issues INSTALL PYTORCH 先声毒人&#xff1a;最好资料就是上面三份资料&#xff0c;可以通过官网明确的获取一手信息&#xff0c;你所遇到的99%的问题都可以找到&#xff0c;明确的解决方案&#xff0c;建议最好看…...

『精』CSS 小技巧之BEM规范

『精』CSS 小技巧之BEM规范 文章目录 『精』CSS 小技巧之BEM规范一、什么是BEM&#xff1f;二、BEM要怎么用&#xff1f;三、不用BEM会少个胳膊吗&#xff1f;&#x1f48a;四、Sass与BEM的结合&#x1f388;五、块与修饰符应放在一块&#x1f47f;参考资料&#x1f498;推荐博…...

vue3-12

需求是用户如果登录了&#xff0c;可以访问主页&#xff0c;如果没有登录&#xff0c;则不能访问主页&#xff0c;随后跳转到登录界面&#xff0c;让用户登录 实现思路&#xff0c;在用户登录之前做一个检查&#xff0c;如果登录了&#xff0c;则token是存在的&#xff0c;则放…...

操作系统期末复习

分段存储管理方式 某采用段式存储管理的系统为装入主存的一个作业建立了如下段表&#xff1a; 段号 段长 主存起始地址 0 660 210 1 140 3300 2 100 90 3 580 1237 4 960 1959 &#xff08;1&#xff09;计算该作业访问[0&#xff0c;432]&#xff0c;[1&am…...

element el-table实现可进行横向拖拽滚动

【问题】表格横向太长&#xff0c;表格横向滚动条位于最底部&#xff0c;需将页面滚动至最底部才可左右拖动表格&#xff0c;用户体验感不好 【需求】基于elment的el-table组件生成的表格&#xff0c;使其可以横向拖拽滚动 【实现】灵感来源于这篇文章【Vue】表格可拖拽滚动&am…...

【兔子王赠书第14期】《YOLO目标检测》涵盖众多目标检测框架,附赠源代码和全书彩图!

文章目录 写在前面YOLO目标检测推荐图书本书特色内容简介作者简介 推荐理由粉丝福利写在后面 写在前面 小伙伴们好久不见吖&#xff0c;本期博主给大家推荐一本关于YOLO目标检测的图书&#xff0c;该书侧重目标检测的基础知识&#xff0c;包含丰富的实践内容&#xff0c;是目标…...

WPF 基础入门(样式)

3.1 一般样式 <Grid Margin"10"><TextBlock Text"Style test" Foreground"Red" FontSize"20"/> </Grid> 3.2内嵌样式 直接在控件上定义样式&#xff0c;如下所示&#xff1a; <Grid Margin"10">…...

Java ArrayList在遍历时删除元素

文章目录 1. Arrays.asList()获取到的ArrayList只能遍历&#xff0c;不能增加或删除元素2. java.util.ArrayList.SubList有实现add()、remove()方法3. 遍历集合时对元素重新赋值、对元素中的属性赋值、删除元素、新增元素3.1 普通for循环3.2 增强for循环3.3 forEach循环3.4 str…...

多模态大模型的前世今生

1 引言 前段时间 ChatGPT 进行了一轮重大更新&#xff1a;多模态上线&#xff0c;能说话&#xff0c;会看图&#xff01;微软发了一篇长达 166 页的 GPT-4V 测评论文&#xff0c;一时间又带起了一阵多模态的热议&#xff0c;随后像是 LLaVA-1.5、CogVLM、MiniGPT-5 等研究工作…...

Android studio 花式按键

一、activity_main.xml代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.a…...

使用spring boot实现异常的统一返回

在这个前后端分离的时代&#xff0c;一个 统一的数据格式非常重要。本次我们实现用spring boot实现一下返回给前端数据的统一格式&#xff0c;不再出现服务器500的错误。 新建一个spring boot项目&#xff0c;并导入knife4j的依赖。 写一个controller控制器&#xff0c;用来是…...

2023-12-11 LeetCode每日一题(最小体力消耗路径)

2023-12-11每日一题 一、题目编号 1631. 最小体力消耗路径二、题目链接 点击跳转到题目位置 三、题目描述 你准备参加一场远足活动。给你一个二维 rows x columns 的地图 heights &#xff0c;其中 heights[row][col] 表示格子 (row, col) 的高度。一开始你在最左上角的格…...

PID为1的僵尸进程的产生及清理

父进程PID为1的僵尸进程通常是由init系统&#xff08;在Linux系统中通常是systemd&#xff09;产生的。这种情况通常发生在以下几种情况&#xff1a; 子进程结束&#xff0c;但其父进程没有正确地调用wait()或waitpid()系统调用来获取子进程的退出状态。在这种情况下&#xff0…...

043、循环神经网络

之——RNN基础 杂谈 第一个对于序列模型的网络&#xff0c;RNN。 正文 1.潜变量自回归模型 潜变量总结过去的信息&#xff0c;再和当前信息一起结合出新的信息。 2.RNN 循环神经网络将观察作为x&#xff0c;与前层隐变量结合得到输出 其中Whh蕴含了整个模型的时序信息&#xf…...

node使用nodemonjs自动启动项目

安装 npm install -g nodemon使用方法 我这里用的是electron项目为例package.json配置 {"name": "my-electron-app","version": "1.0.0","description": "Hello World!","main": "main.js"…...

Ts自封装WebSocket心跳重连

WebSocket是一种在单个TCP连接上进行全双工通信的协议&#xff0c;允许客户端和服务器之间进行双向实时通信。 所谓心跳机制&#xff0c;就是在长时间不使用WebSocket连接的情况下&#xff0c;通过服务器与客户端之间按照一定时间间隔进行少量数据的通信来达到确认连接稳定的手…...

【unity学习笔记】捏人+眨眼效果+口型效果

一、vriod捏人 1.在vroidstudio软件中捏人 2.导出模型&#xff08;.vrm) 二、vrid导入unity的插件 1.在Git上搜索、打开univrm。 2.找到release页面找到合适的插件版本。&#xff08;VRM-0.116.0_0f6c&#xff09; 3.将univrm导入到工程中&#xff08;assets&#xff09;。 三…...