SpringBoot 项目如何集成 JWT
SpringBoot 项目如何集成 JWT
JWT
JSON Web Token (JWT) 是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为 JSON 对象在各方之间安全地传输信息。
在 Oauth2 中,其实就是返回访问令牌 (access_token)代替用户名和密码来使用,访问令牌只需要满足唯一性,不可猜测性等条件即可,那么 JWT 结构化令牌也可以达到这样的效果,且内部可以包含一些更有效的信息
{
"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIxIiwiZXhwIjoxNzMzNTYwMzY5fQ.AC3oOXbpz2cLYnCHTcYUCQxdTe_dqvwSSDpGi7W2IXg"
}
比如上面这个 token ,看起来只是一串由三个.
分割出的字符串罢了,但是如果你放到 https://jwt.io/ 上进行解析,就可以得到下面的结果:
JWT 可以分为以下三个部分:
- HEADER 表示装载令牌类型和算法等信息,是 JWT 的头部。其中,typ 表示第二部分 PAYLOAD 是 JWT 类型,alg 表示使用 HS256 对称签名的算法。
- PAYLOAD 表示是 JWT 的数据体,代表了一组数据。
- SIGNATURE 表示对 JWT 信息的签名,虽然有了 HEADER 和 PAYLOAD,信息已经可以进行传输了,但是我们为了安全,需要对其进行加密签名,SIGNATURE 就是对其进行加密签名的结果。
为什么需要加密签名呢,以登录流程为例,后端服务在用户登录成功后,返回了 jwt 并存放到了 cookie 里,前端每次发请求都携带这个 jwt,后端收到后,根据加密时候所用的加密串进行解密,如果解密成功,说明 jwt 没有被伪造,继续执行请求,否则认为这个 jwt 是伪造的,返回错误信息,需要前端重新登录,获取新 jwt。
SpringBoot 集成 JWT
- 登录时的返回信息中为用户新增token字段
package com.zwj.pojo;import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;@Data
@AllArgsConstructor
@NoArgsConstructor
// 这个类用于登录成功时返回,由前端存入 cookie 里,用于一些展示,比如 #{username},欢迎使用
public class UserCookie {private String username;private String email;private String token;
}
package com.zwj.utils;import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.zwj.pojo.Admin;
import com.zwj.service.AdminService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;@Component
@Slf4j
public class TokenUtil {// 生成 Token 的方法public static String genToken(String adminId, String sign) {return JWT.create().withAudience(adminId) // 将 adminId 保存到 token 里面,作为负载.withExpiresAt(DateUtil.offsetHour(new Date(), 2)) // 2小时后token过期.sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的签名密钥}
}
package com.zwj.controller;import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.MD5;
import com.zwj.controller.request.AdminPageRequest;
import com.zwj.controller.request.UserPageRequest;
import com.zwj.pojo.Admin;
import com.zwj.service.AdminService;
import com.zwj.utils.MD5Util;
import com.zwj.utils.Result;
import com.zwj.utils.TokenUtil;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import java.security.Security;
import java.util.Date;
import java.util.List;@RestController
@RequestMapping("/admin")
public class AdminController {@ResourceAdminServiceImpl adminService;@PostMapping("/login")public Result<?> login(@RequestBody Admin user){// 密码进行 MD5 加密user.setPassword(MD5Util.MD5Encode(user.getPassword(),"UTF-8"));// 找到登录的这个用户Admin admin = adminService.getAdminByUsernameAndPassword(user.getUsername(),user.getPassword());if (admin != null){if (admin.getStatus() == 1){UserCookie cookie = new UserCookie();// 为其生成 jwt,负载是用户ID,签名密钥是用户密码的MD5加密结果String token = TokenUtil.genToken(String.valueOf(admin.getId()), admin.getPassword());cookie.setToken(token);cookie.setUsername(admin.getUsername());// 返回这个用户信息,用于前端存入 cookiereturn Result.success(cookie);} else {return Result.error("您的权限已冻结!");}}return Result.error("用户名或密码错误!");}}
- 前端将信息存入 cookie 中
request.post("/admin/login", this.admin).then(res => {if (res.code === '200'){if (res.data != null){// 登录成功,将返回结果里的数据存入 cookie 中,key 是 'user'this.loginAdmin = res.data;Cookies.set('user', JSON.stringify(this.loginAdmin));}} else {this.$notify.error(res.msg);}
})
- 前端设置后续每次发送请求时,带上这个 token
request.interceptors.request.use(config => {config.headers['Content-Type'] = 'application/json;charset=utf-8';// 从 cookie 里取当前登录者信息let user = Cookies.get('user');if (user != null){// 如果能取到,放在 header 里config.headers['token'] = JSON.parse(user).token;}return config;
}, error => {return Promise.reject(error)
});
- 后端设置拦截器,拦截除登录、重置密码等不需要 token 外的所有请求
package com.zwj.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@AutowiredJwtInterceptor jwtInterceptor;@Overridepublic void configurePathMatch(PathMatchConfigurer configurer) {// 指定controller统一的接口前缀configurer.addPathPrefix("/api", clazz -> clazz.isAnnotationPresent(RestController.class));}// 加自定义拦截器JwtInterceptor,设置拦截规则@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 这里的 jwtInterceptor 是我们自定义的,定义内容在下一个代码块registry.addInterceptor(jwtInterceptor).addPathPatterns("/api/**").excludePathPatterns("/api/admin/login","/api/files/**");}
}
package com.zwj.config;import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.zwj.pojo.Admin;
import com.zwj.excepion.ServiceException;
import com.zwj.service.AdminService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {private static final String ERROR_CODE_401 = "401";@Resourceprivate AdminService adminService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 从 header 里取 tokenString token = request.getHeader("token");// 如果没有直接抛出异常if (StrUtil.isBlank(token)) {throw new ServiceException(ERROR_CODE_401, "无token,请重新登录");}// 获取 token 中的 adminIdString adminId;Admin admin;try {adminId = JWT.decode(token).getAudience().get(0);// 根据 token 中的 adminId 查询数据库admin = adminService.getAdminById(Integer.parseInt(adminId));} catch (Exception e) {String errMsg = "token验证失败,请重新登录";log.error(errMsg + ", token=" + token, e);throw new ServiceException(ERROR_CODE_401, errMsg);}if (admin == null) {throw new ServiceException(ERROR_CODE_401, "用户不存在,请重新登录");}try {// 用户密码加签验证 tokenJWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(admin.getPassword())).build();jwtVerifier.verify(token); // 验证token} catch (JWTVerificationException e) {throw new ServiceException(ERROR_CODE_401, "token验证失败,请重新登录");}return true;}
}
以上就是 SpringBoot 集成 JWT 的流程,其中的重点:
- 生成 token 时的内容和顺序
比如这里,设置了 audience 的值是 adminId,签名密钥是该用户的密码的 MD5 加密结果
- 验证的时候要按照相同的顺序取,使用相同的密钥验证
当然也可以不选择密码作为密钥验证,使用任意字符串也可以,但是使用密码做验证有这样的好处:如果用户此时修改了密码,那么这个 JWT 也就随之失效了,验证签名的时候会校验失败。但是如果使用其他常量作为密钥,就只能等待 JWT 主动到期,在修改密码到主动到期这段时间,JWT 依然可以被正常使用。
相关文章:
SpringBoot 项目如何集成 JWT
SpringBoot 项目如何集成 JWT JWT JSON Web Token (JWT) 是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为 JSON 对象在各方之间安全地传输信息。 在 Oauth2 中,其实就是返回访问令牌 (access_token&#…...
如何查看电脑刷新率
Windows 系统 通过显示设置查看: 右键点击桌面空白处,选择 “显示设置”。在打开的窗口中,找到 “高级显示设置”。点击 “显示适配器属性”。在弹出的窗口中,选择 “监视器” 选项卡,即可看到当前的屏幕刷新率。使用 …...
MVC基础——市场管理系统(一)
文章目录 项目地址一、创建项目结构1.1 创建程序以及Controller1.2 创建View1.3 创建Models层,并且在Edit页面显示1.4 创建Layou模板页面1.5 创建静态文件css中间件二、Categories的CRUD2.1 使用静态仓库存储数据2.2 将Categorie的列表显示在页面中(List)2.3 创建_ViewImport.…...
面向对象中多态的含义
多态性的定义 多态(Polymorphism)是面向对象编程中的一个重要概念。它是指同一个函数名或操作符在不同的对象或情境下具有不同的行为。简单来说,就是 “多种形态”。例如,在一个图形处理程序中,有 “计算面积” 这个操…...
L2G3000-LMDeploy 量化部署实践
文章目录 LMDeploy 量化部署实践闯关任务环境配置W4A16 量化 KV cacheKV cache 量化Function call LMDeploy 量化部署实践闯关任务 环境配置 conda create -n lmdeploy python3.10 -y conda activate lmdeploy conda install pytorch2.1.2 torchvision0.16.2 torchaudio2.1.…...
ubuntu下的chattts 学习5:Example: self introduction
代码 import ChatTTS import torch import torchaudiochat ChatTTS.Chat() chat.load(compileFalse) # Set to True for better performance ################################### inputs_en """ chat T T S is a text to speech model designed for dialogu…...
IDEA的service窗口中启动类是灰色且容易消失
大家在学习Spring Cloud的过程中,随着项目的深入,会分出很多个微服务,当我们的服务数量大于等于三个的时候,IDEA会给我们的服务整理起来,类似于这样 但是当我们的微服务数量达到5个以上的时候,再启动服务的时候,服务的启动类就会变成灰色,而且还容易丢失 解决方法 我们按住…...
vue中pdf.js的使用,包括pdf显示,跳转指定页面,高亮关键词
目录 一、下载pdf.js 二、引入到本地的项目中 三、实现预览pdf 四、跳转到指定页面 五、利用pdf里面的find查找关键词 六、修改页面大小为实际大小 一、下载pdf.js https://github.com/mozilla/pdf.js 里面有很多的版本, 高版本的可能浏览器不兼容或者还要考…...
Cherno C++学习笔记 P32 字符串
这篇文章我们来讲字符串。字符串可以说是最重要的变量类型了,因为对字符串的读写极大地影响到我们的程序和用户之间的交互。甚至很多很庞大的程序就只是在处理字符串。 对于字符串,我们同时需要有关于数组和指针的关系,字符串的实现与数组是…...
【C++初阶】第7课—标准模版库STL(string_1)
文章目录 1. 什么是STL2. STL六大组件3. 标准库中string类3.1 auto关键字3.2 范围for3.3 string类的类型3.4 string类的常用接口(string类对象的常见构造)3.5 string的析构和赋值运算符重载3.6 string类对象的容量操作 1. 什么是STL STL(standard template library—标准模板库…...
GESP202306 一级【时间规划】题解(AC)
》》》点我查看「视频」详解》》》 AC_Code #include <bits/stdc.h> using namespace std;int main() {int h1, m1, h2, m2;cin >> h1 >> m1;cin >> h2 >> m2;h1 h1 * 60 m1;h2 h2 * 60 m2;cout << h2 - h1;return 0; }》》》点我查…...
React基础知识四 Hooks
什么是hooks? (coderwhy) hooks是react 16.8(2019年)出的新特性。 react有两种形式来创建组件——类式和函数式。在hooks之前类式组件就是react最主流的编程方式。 这个时候,函数式组件是非常鸡肋的,几乎没什么用。因…...
Linux服务器通用安全加固指南
1、保护引导过程(以Grub引导为例) 在 /etc/inittab 中添加 sp:S:respawn:/sbin/sulogin,以确保当切换到单用户模式时 运行级的配置要求输入 root 密码: cp /etc/inittab / etc/initab .bak vim /etc/inittab 退出:es…...
vsphere vcenter web 界面的介绍
这是主页的页面...
分类算法中的样本不平衡问题及其解决方案
一、样本不平衡问题概述 在机器学习的分类任务中,样本不平衡是指不同类别训练样本数量存在显著差异的现象。这一差异会给模型训练和性能评估带来挑战,尤其在处理少数类样本时,模型可能难以有效学习其特征。 以二分类为例,理想情况…...
[LitCTF 2023]破损的图片(初级)
[LitCTF 2023]破损的图片(初级) 我们下载附件得到一个没有后缀的文件,拖去010看一看,发现本来应该是文件头的那部分不大对劲,结合后面四个点以及IHDR,大致也应该知道是啥了 修改第一行为png 89 50 4E 47 0D 0A 1A 0A 00 00 00 …...
最新道客巴巴怎么免费下载文档方法
一、利用浏览器插件 插件自动识别下载:对于经常需要下载道客巴巴文档的人来说,安装浏览器插件是不错的选择。如Chrome浏览器上的一些插件(如PDF在线转换器等),安装后,在浏览器中打开道客巴巴文档ÿ…...
Bert的Transformer原理
多义词如何应对: 答:通过Self attention,不同的上下文,对同一个"苹果",得到截然不同的embedding激活值; Multi-head的作用: 有些类似CNN里用的多个卷积核得到多个Channel的特征图&…...
多人聊天室 NIO模型实现
NIO编程模型 Selector监听客户端不同的zhuangtai不同客户端触发不同的状态后,交由相应的handles处理Selector和对应的处理handles都是在同一线程上实现的 I/O多路复用 在Java中,I/O多路复用是一种技术,它允许单个线程处理多个输入/输出&…...
vue.js学习(day 20)
综合案例:购物车 数据渲染 构建cart购物车模块 准备后端接口服务环境 请求数据存入vuex cart.js // 新建购物车模块 import axios from axios export default {namespaced: true,state () {return {// 购物车数据 [{},{}]list: []}},mutations: {updateList (…...
蓝桥杯二分题
P1083 [NOIP2012 提高组] 借教室 题目描述 在大学期间,经常需要租借教室。大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。 面对海量租…...
通过 CC-Link IEFB 转 Modbus RTU 网关达成三菱 FX5U PLC 与 RS485 温湿度传感器通信的配置实例展示
一. 案例背景 在某一化工厂现场,现场的设备是三菱FX5UPLC为了避免因为工作环境存在潮湿度较高性、较高温度等对员工造成不健康或危险的现象,现决定在现场装数多台温湿度传感器。通过捷米特JM-CCLKIE-RTU网关将三菱PLC及温湿度传感器连接起来并连接上位机…...
视频质量评价算法 DOVER 使用教程
DOVER 介绍 DOVER是为ICCV2023会议论文“Exploring Video Quality Assessment on User Generated Contents from Aesthetic and Technical Perspectives”提供的官方代码、演示和权重的项目。DOVER(Disentangled Objective Video Quality Evaluator)是一个用于评估用户生成内…...
视频编辑技术:一键生成混剪视频的AI技术应用
随着视频内容的爆炸式增长,视频编辑技术也在不断进步。本文将探讨如何利用AI技术,实现一键生成混剪视频,并自动添加配音和字幕,以提高视频编辑的效率和质量。 AI技术在视频编辑中的应用 AI技术在视频编辑领域的应用越来越广泛&am…...
精确的单向延迟测量:使用普通硬件和软件
论文标题:Precise One-way Delay Measurement with Common Hardware and Software(精确的单向延迟测量:使用普通硬件和软件) 作者信息:Maciej Muehleisen 和 Mazen Abdel Latif,来自Ericsson Research Eri…...
【博士每天一篇文献-COIL算法】Co-transport for class-incremental learning
1 介绍 年份:2021 会议:2021ACM Zhou D W, Ye H J, Zhan D C. Co-transport for class-incremental learning[C]//Proceedings of the 29th ACM International Conference on Multimedia. 2021: 1645-1654. 本文提出的算法是CO-transport for clas…...
AI与BI的火花:大语言模型如何重塑商业智能的未来
大家好,我是独孤风。 在当今这个数据驱动的时代,企业对于信息的需求如同对于氧气的需求一般至关重要。商业智能(BI)作为企业获取、分析和呈现数据的关键工具,正在经历一场深刻的变革,而这一变革的催化剂正是…...
C++设计模式(建造者、中介者、备忘录)
一、建造者模式 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 示例: //房子(产品类) class House { private:int rooms;int windows;string decoration; public:void setRooms(int r) {rooms …...
【数据结构】遍历二叉树
遍历二叉树的算法描述(递归定义) 先序遍历 若二叉树为空,则空操作; 否则 (1)访问根节点 (2)先序遍历左子树 (3)先序遍历右子树 中序遍历 若二叉树为空…...
鸿蒙获取 APP 信息及手机信息
前言:获取 APP 版本信息可以通过 bundleManager.getBundleInfoForSelfSync(bundleFlags) 去获取,获取手机信息可以通过 kit.BasicServicesKit 库去获取,以下是封装好的工具类。 import bundleManager from ohos.bundle.bundleManager; impo…...
OpenWRT下深入了解IPv6——SLAAC
一、SLAAC(无状态地址自动配置) 1.基本原理 SLAAC 是 IPv6 中的一种地址自动配置机制,它允许设备根据网络中的路由器通告信息和自身的 MAC 地址自动生成 IPv6 地址。在 IPv6 网络中,MAC 地址长度为 48 位,而 IPv6 地…...
UE5水文章 UI按钮样式快捷复制黏贴
shift右键拷贝 shift右键黏贴...
迭代器模式的理解和实践
引言 在软件开发中,我们经常需要遍历容器对象(如数组、列表、集合等)中的元素。如果每个容器对象都实现自己的遍历算法,那么代码将会变得冗余且难以维护。为了解决这个问题,迭代器模式应运而生。迭代器模式是一种行为型…...
Python __func 与 _func 的区别引起的思考
文章目录 __function_function深入名称修饰机制名称修饰的目的实现原理 属性访问控制的高级模式基本模式扩展复杂的转换和验证逻辑带有日志和审计的访问控制 如果突然让我说一说 Python中的__function和_function有哪些不同的约定和用途,我好像一下子没法说出很多东…...
python学opencv|读取视频(二)制作gif
【1】引言 前述已经完成了图像和视频的读取学习,本次课学习制作gif格式动图。 【2】教程 实际上想制作gif格式动图是一个顺理成章的操作,完成了图像和视频的处理,那就自然而然会对gif的处理也产生兴趣。 不过在opencv官网、matplotlib官网…...
Redmi AX3000 (RA81) 路由器恢复原厂固件
最近给Redmi AX3000 (RA81) 刷了OpenWrt固件,但是存在各种小问题,因此决定刷回原厂固件。刷机之前保证能够访问路由器ssh,否则请百度救砖教程。 准备工具 Redmi AX3000 (RA81) 原厂分区文件 [github下载地址 / csdn下载地址]小米路由器修复…...
【调试工具】USB 转 UART 适配器(USB 转 TTL)
「USB 转 TTL 转换器」是错误的叫法,正确的叫法应该为 「USB 转 UART 适配器」。 Device connection 注意端口的交叉连接,Device1_TX<---->Device2_RX USB-to-UART adapter GND 记得接地。 使用: 当 TX,RX 需要电平为 0-3.3V 时&am…...
【YOLO部署Android安卓手机APP】YOLOv11部署到安卓实时目标检测识别——以火焰烟雾目标检测识别举例(可自定义更换其他目标)
前言:本项目基于YOLOv11部署到手机APP实现对火焰烟雾的检测识别,当然,以此你可以按照本项目开发步骤扩展更换为其他目标进行检测,例如更换为车牌、手势、人脸面部活动、人脸表情、火焰烟雾、行人、口罩、行为、水果、植物、农作物等等部署手机APP进行检测。本文为详细设计/…...
Python 中的 __slots__ 属性有什么作用?
__slots__ 是Python类中的一种特殊属性,它允许你显式地声明一个类的实例可以拥有的属性。 这不仅有助于节省内存,还能提高属性访问的速度,并且防止动态添加不属于设计的属性。 在大型项目或者对性能敏感的应用程序中,正确使用 _…...
【H2O2|全栈】Node.js与MySQL连接
目录 前言 开篇语 准备工作 初始配置 创建连接池 操作数据库 封装方法 结束语 前言 开篇语 本节讲解如何使用Node.js实现与MySQL数据库的连接,并将该过程进行函数封装。 与基础部分的语法相比,ES6的语法进行了一些更加严谨的约束和优化&#…...
【大数据技术基础】 课程 第3章 Hadoop的安装和使用 大数据基础编程、实验和案例教程(第2版)
第3章 Hadoop的安装和使用 3.1 Hadoop简介 Hadoop是Apache软件基金会旗下的一个开源分布式计算平台,为用户提供了系统底层细节透明的分布式基础架构。Hadoop是基于Java语言开发的,具有很好的跨平台特性,并且可以部署在廉价的计算机集群中。H…...
DDR4与DDR3服务器内存的关键区别有哪些?
内存作为服务器性能的关键组件之一,已经经历了从DDR3到DDR4的过渡。DDR4内存相较于DDR3在多个方面有所提升,包括速度、带宽、功耗以及数据传输效率等。然而,尽管DDR4内存在性能上占有优势,DDR3内存依然在一些特定场景中得到了广泛…...
OceanBase 的探索与实践
作者:来自 vivo 互联网数据库团队- Xu Shaohui 本文总结了目前我们遇到的痛点问题并通过 OceanBase 的技术方案解决了这些痛点问题,完整的描述了 OceanBase 的实施落地,通过迁移到 OceanBase 实践案例中遇到的问题与解决方案让大家能更好的了…...
2024年安全员-A证证模拟考试题库及安全员-A证理论考试试题
2024年安全员-A证模拟考试题库及理论考试试题(一) 单选题 根据《建筑施工企业主要负责人、项目负责人和专职安全生产管理人员安全生产管理规定》,项目负责人每月带班生产时间不得少于本月施工时间的( )。 A. 60% B. …...
安装Docker并使用WSL
引言 Windows Subsystem for Linux (WSL) 是一个在Windows上运行Linux二进制可执行文件(ELF格式)的兼容层。它允许开发者直接在Windows上运行Linux环境,而无需使用虚拟机。Docker是一个开源的应用容器引擎,它允许开发者打包应用以…...
【TCP 网络通信(发送端 + 接收端)实例 —— Python】
TCP 网络通信(发送端 接收端)实例 —— Python 1. 引言2. 创建 TCP 服务器(接收端)2.1 代码示例:TCP 服务器2.2 代码解释: 3. 创建 TCP 客户端(发送端)3.1 代码示例:TCP…...
PostgreSQL和Oracle的sql差异
PostgreSQL和Oracle的sql差异 1.rownum (1)Oracle分页查询使用rownum,PostgreSQL使用limit offset ORACLEPOSTGRESQLselect * from (select rownum r,e.* from emp e where rownum <5) t where r>0;select * from emp limit 5 offset…...
阻塞队列详解
阻塞队列介绍 队列 是限定在一端进行插入,另一端进行删除的特殊线性表。先进先出(FIFO)线性表。允许出队的一端称为队头,允许入队的一端称为队尾。 数据结构演示网站: https://www.cs.usfca.edu/~galles/visualization/Algorithms.html Q…...
kali安装谷歌输入法
临时隐匿你IP地址 ifconfig 查询kali现在所用ip ifconfig eth0 所需要修改的ip/掩码24 修改临时ip格式命令 安装中文输入法命令 临时隐匿你IP地址 ifconfig 查询kali现在所用ip ifconfig eth0 所需要修改的ip/掩码24 修改临时ip格式命令安装中文输入法命令 apt-get in…...
C语言:编译与链接
本篇博客给大家带来的是代码从运行到生成可执行文件的流程和原理 🐟🐟文章专栏:C语言 🚀🚀若有问题评论区下讨论,我会及时回答 ❤❤欢迎大家点赞、收藏、分享 你们的支持就是我创造的动力 今日思想…...