JWT令牌技术
一、JWT令牌的定义JWT(JSON Web Token)是一种基于JSON的开放标准(RFC 7519),用于在网络应用间安全传递声明信息。其核心特点是通过数字签名或加密实现数据的自包含性和防篡改,无需依赖中心化存储即可完成身份验证。 核心特性 自包含性:令牌内直接携带用户身份、权限等关键信息,服务端无需查询数据库即可完成验证。 无状态性:适用于分布式系统,避免传统Session机制中的会话同步问题 跨域支持:通过HTTP头部传递,天然适配微服务架构和跨域资源共享(CORS) 二、JWT令牌的组成结构JWT由三部分通过点(.)连接组成,格式为:Header.Payload.Signature 1. 头部(Header) 作用:声明令牌类型与签名算法。 编码方式:Base64URL编码 2....
关于黑马点评项目Lua脚本的使用
最近在学习黑马程序员的黑马点评项目中,使用到Lua脚本来确保程序的原子性。下面是对该Lua脚本使用的总结 Lua脚本内容:以下是输出锁的脚本内容 12345678--锁的线程标识KEY[1],线程标识ARGV[1]-- 判断线程标识是否与锁中的线程标识一致if(redis.call('get',KEY[1])==ARGV[1]) then-- 一致,删除锁return redis.call('del',KEY[1])end--不一致,直接返回return 0 Lua脚本的加载:123456private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;static { UNLOCK_SCRIPT = new DefaultRedisScript<>(); UNLOCK_SCRIPT.setLocation(new ClassPathResource("unlock.lua")); ...
你以为空指针异常只是新手专利?这些坑你可能每天都在踩!
你以为空指针异常只是新手专利?这些坑你可能每天都在踩!空指针异常(NullPointerException,简称NPE)堪称Java程序员职业生涯的“终身伴侣”,但很多人对它的认知还停留在“对象没初始化”的初级阶段。今天我就带你去全面的了解空指针异常。 一、NPE的诞生:你以为的vs实际发生的NPE的本质是在空对象(null)上调用方法或访问属性,但实际开发中,它常以意想不到的方式出现: 123// 教科书级案例(但现实中很少这么直白)String str = null;System.out.println(str.length()); // 直接爆炸 现实中更多是间接引爆,比如: 二、NPE的八种“阴人”姿势1. 自动拆箱:包装类的温柔陷阱12Integer total = null;int report = total; // 自动拆箱 → total.intValue(),原地爆炸! 💡避坑:包装类变量拆箱前必须判空。 2. 方法链调用:连环爆炸现场12User user = getUserById(10086);String city =...
你每天都在用的装箱和拆箱,可能藏着这些坑!
你每天都在用的装箱和拆箱,可能藏着这些坑!Java程序员几乎每天都在和int、Integer打交道,但很多人对**装箱(Boxing)和拆箱(Unboxing)**的理解,还停留在“自动转换”的层面。今天我们就用最直白的例子,扒开这层语法糖的外衣,看看背后藏着哪些意想不到的坑。 一、基础篇:什么是装箱和拆箱?1. 原始类型 vs 包装类 原始类型:int、boolean、double等(直接存数据,快但功能少) 包装类:Integer、Boolean、Double等(对象,能调用方法,支持null) 12int num = 10; // 原始类型,直接存数值Integer boxedNum = Integer.valueOf(10); // 包装类对象 2. 手动装箱与拆箱(Java 5之前) 装箱:把原始类型“包”成对象 → Integer.valueOf(10) 拆箱:从对象中“拆”出原始值 → boxedNum.intValue() 123456// 手动装箱(繁琐)List<Integer> list = new...
LeetCode-两数之和
两数之和给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。 示例 1: 123输入:nums = [2,7,11,15], target = 9输出:[0,1]解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。 示例 2: 12输入:nums = [3,2,4], target = 6输出:[1,2] 示例 3: 12输入:nums = [3,3], target = 6输出:[0,1] 实现代码: 12345678910111213class Solution { public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> numMap = new HashMap<>(); for (int i =...
Spring事务失效的十大坑,你踩过几个?
Spring事务失效的十大坑,你踩过几个?Spring的@Transactional注解用起来方便,但稍不注意就会掉进“事务失效”的坑里。今天我们就来盘一盘这些常见的失效场景,帮你绕开雷区,写出稳定可靠的事务代码! 1. 非public方法加注解:白忙活@Transactional默认只对public方法生效。如果你在private、protected或默认权限的方法上加注解,Spring压根不会代理这个方法,事务自然不生效。例子: 12@Transactional private void saveData() { /* 操作数据库 */ } 解决:老老实实改成public方法。 2. 自调用:自己坑自己在同一个类里,方法A调用加了@Transactional的方法B,事务会失效。因为Spring的事务代理机制是通过AOP动态生成的,直接通过this.方法B()调用会绕开代理对象。例子: 12345public void methodA() { this.methodB(); // 事务无效! }...
手把手教你玩转MyBatis-Plus自定义SQL:告别死板操作,解锁复杂场景
一、为什么需要自定义SQL?你可能已经习惯了MyBatis-Plus的QueryWrapper,用它写简单的查询确实爽到飞起,但遇到下面这些场景时,是不是感觉被捆住了手脚? 多表联查:想查用户信息连带部门名称,结果发现Join操作根本没法用Wrapper搞定 复杂统计:老板让你统计每个部门的平均工资+最高年龄,手写SQL又得掏出来 特殊语法:比如Oracle的WITH语句、SQL Server的TOP,MP的Wrapper根本不支持 性能优化:某些场景必须手写优化过的SQL,自动生成的SQL效率太低 这时候,自定义SQL就是你的救命稻草! 二、两种姿势写自定义SQL姿势1:注解式(适合简单SQL)直接在Mapper接口的方法上加@Select、@Update等注解: 123456789101112131415public interface UserMapper extends BaseMapper<User> { // 案例:查询指定部门下薪资最高的用户(假设需要复杂子查询) @Select("SELECT * FROM...
手把手玩转MyBatis-Plus条件构造器:告别硬编码,解锁丝滑数据库操作
一、为什么你需要条件构造器?想象一下这个场景:你要从用户表里筛选出名字带”张”、年龄在20-30岁之间,并且最近一个月登录过的用户。如果手写 SQL,光是处理动态条件就得写一堆if判断,不仅麻烦还容易出错。MyBatis-Plus 的条件构造器(Wrapper)就是你的救星! 它能帮你:✅ 用链式调用代替繁琐的 SQL 拼接✅ 避免字段名硬编码引发的低级错误✅ 轻松实现动态查询/更新条件 二、四大金刚:条件构造器全家桶1. QueryWrapper:直男型操作 特点:直接写字段名,适合快速上手 示例:找名字叫”John”的程序员小哥 1234QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.eq("name", "John") .eq("job", "程序员");List<User> users =...
MyBatis-Plus引入
在mybatis中,我们常常要进行单表 CRUD 操作,而这一类的操作虽然简单,但是繁琐,造成大量时间浪费。像这张图 我们通过使用MbatisPlus,可以快速进行这一类的操作,节省时间。并且使用它,只做增强不做改变,引入MbatisPlus不会对现有工程产生影响。以下是引用的教程。 1.在pom.xml文件中引用起步依赖 123456<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version></dependency> 2.在对应的mapper层接口继承BaseMapper接口,<>里面填写实体类的类型 123public interface UserMapper extends BaseMapper<User>...
REST
REST一、REST 是什么?REST(Representational State Transfer) 是一种基于 HTTP 协议的 软件架构风格,由 Roy Fielding 在 2000 年提出。它强调以 资源(Resource) 为核心,通过统一的接口(如 HTTP 方法)对资源进行操作,适用于构建分布式、可扩展的 Web 服务。 传统风格资源描述形式 12http://localhost/user/getById?id=1http://localhost/user/saveUser REST风格描述形式: 12http://localhost/user/1http://localhost/user 我们可以看到,这种风格的描述形式隐藏了资源的访问行为,无法通过地址得知资源是何种操作 那要怎么区分呢? 按照REST风格访问资源时使用行为动作区分对资源进行了何种操作 12345http://localhost/users 查询全部用户信息GET (查询)http://1ocalhost/users/1 直询指定用户信息GET...
