前言:涉及知识范围(学习内容)
非框架部分:map,Iterator
框架部分:ssm,jwt
Java迭代器(Iterator)是 Java 集合框架中的一种机制,是一种用于遍历集合(如列表、集合和映射等)的接口。
它提供了一种统一的方式来访问集合中的元素
map(映射):用于存储键值对,常见的有哈希表map与黑红树map
Map<String, Integer> hashMap = new HashMap<>();
Map<String, Integer> treeMap = new TreeMap<>();
|----|-----------------|-------------------|
| | HashMap | TreeMap |
| 特性 | 基于哈希表实现的键值对存储结构 | 基于红黑树实现的有序键值对存储结构 |
| 优点 | 高效的查找、插入和删除操作 | 有序,支持按照键的顺序遍历 |
| 缺点 | 无序,不保证顺序插 | 插入和删除相对较慢 |
++在不深入的情况下,暂时先把它当成一个特殊的对象(数组)++
提到键值对,那么第一时间应该会想到数据库和引用数据类型:对象,数组
提到映射,在使用mybtis的时候,我们涉及到了这一概念,它的本质是一种元素与元素之间的关系
具体点:一对一,一对二,一对三的关系,无法逆转(单向)
例子:你能直接通过值去找到数组和对象的键吗?很显然,不能,要通过一些手段才可以找到
JWT: JSON Web Token

三部分组成:算法和令牌类型,数据,验证签名
在生成jwt的时候,就是按照这三种形式去自定义一个jwt令牌
maven依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.3.0</version>
</dependency>
依赖导入完后,开始进入正片,那么前面的内容是干什么的?大致了解一下就好了
我们会使用到JWT这个类
java
public class JWT {
private final JWTParser parser = new JWTParser();
public JWT() {
}
public DecodedJWT decodeJwt(String token) throws JWTDecodeException {
return new JWTDecoder(this.parser, token);
}
public static DecodedJWT decode(String token) throws JWTDecodeException {
return new JWTDecoder(token);
}
public static Verification require(Algorithm algorithm) {
return JWTVerifier.init(algorithm);
}
public static JWTCreator.Builder create() {
return JWTCreator.init();
}
}
我们将使用到JWT类中的Builder类型 create方法(函数)和Verification类型 reqiore方法(函数)
前者返回:JWTCreator.init =》中文翻译为JWT生成器
后者返回:JWTVerifier.init(algorithm),翻译 =》JWT验证器(参数为验证签名)
先从生成器开始,它方法类型是一个JWTCreator.Builder对象,并返回初始化器,看看源码

init(),直接 new 了一个Builder类
也就是说Builder是核心中的中心,搞懂Builder就是搞懂JWT生成令牌
在接下来的使用将会一步一步看源码
知道了是生成器是哪个方法,我们直接用就好了
java
@SpringBootTest
@Configuration
class CodeRomaBackendApplicationTests {
@Test
public void JWT(){
JWT.create()
}
}
这样就完成了第一步
按一下.会有很多方法

这里我们回到builder的源码
JWT由三部分组成:算法和令牌类型,数据,验证签名 == header,payload,sign
java
private final Map<String, Object> payloadClaims = new HashMap();
private final Map<String, Object> headerClaims = new HashMap();
在源码中标有这两个变量,那么现在应该可以看懂了吧
一个用来存储header的键值对
另一个用来存储payload的键值对
键值对,键对应性,值对应名,口头说很抽象,还是直接上代码容易点
提一嘴,map.put是存入,类似于实体类中的set方法
java
@SpringBootTest
@Configuration
class CodeRomaBackendApplicationTests {
public void JWT(){
// JWT头部分信息【Header】
Map<String, Object> header = new HashMap<>();
header.put("alg", "HS256");//性为alg,名为HS256
header.put("typ", "JWT");//性为typ,名为JWT
// 载核【Payload】
Map<String, Object> payload = new HashMap<>();
payload.put("sub", "1234567890");//性为sub,名为123456789
payload.put("name","John Doe");//性为name,名为John Doe
payload.put("admin",true);//性为admin,名为true
JWT.create()
.withHeader(header)//头部
.withPayload(payload)//负载
}
}
定义了header和payload信息,有了头和负载,现在就差签名了
第一个对应的header的源码
java
public Builder withHeader(Map<String, Object> headerClaims) {
if (headerClaims == null) {
return this;
} else {
Iterator var2 = headerClaims.entrySet().iterator();
while(var2.hasNext()) {
Map.Entry<String, Object> entry = (Map.Entry)var2.next();
if (entry.getValue() == null) {
this.headerClaims.remove(entry.getKey());
} else {
this.headerClaims.put((String)entry.getKey(), entry.getValue());
}
}
return this;
}
}
第二个对应的payload的源码
java
public Builder withPayload(Map<String, ?> payloadClaims) throws IllegalArgumentException {
if (payloadClaims == null) {
return this;
} else if (!this.validatePayload(payloadClaims)) {
throw new IllegalArgumentException("Claim values must only be of types Map, List, Boolean, Integer, Long, Double, String, Date, Instant, and Null");
} else {
Iterator var2 = payloadClaims.entrySet().iterator();
while(var2.hasNext()) {
Map.Entry<String, ?> entry = (Map.Entry)var2.next();
this.addClaim((String)entry.getKey(), entry.getValue());
}
return this;
}
}
前面的if条件判断语句一般情况下,你只要有内容都是不会有报错的
重点是循环里面的内容,map集合里有一个方法叫getkey和getvalue
Map.Entry是map里的内部接口,在那之前entrySet().iterator();很关键
getKey()
:返回与此条目相关联的键。getValue()
:返回与此条目相关联的值。
将我们存入的map通过循环取出来,使用,用sign结束
java
public String sign(Algorithm algorithm) throws IllegalArgumentException, JWTCreationException {
if (algorithm == null) {
throw new IllegalArgumentException("The Algorithm cannot be null.");
} else {
this.headerClaims.put("alg", algorithm.getName());
if (!this.headerClaims.containsKey("typ")) {
this.headerClaims.put("typ", "JWT");
}
String signingKeyId = algorithm.getSigningKeyId();
if (signingKeyId != null) {
this.withKeyId(signingKeyId);
}
return (new JWTCreator(algorithm, this.headerClaims, this.payloadClaims)).sign();
}
}
哎,它返回一个this.headerClaims是不是意味着header有另一个方法实现
this我们知道,他是隐性调用,那么意味着algorithm里面有这个headerClaims参数
修改一下代码
java
@Test
public void JWT(){
Algorithm algorithm = Algorithm.HMAC256("secret");
// 载核【Payload】
Map<String, Object> payload = new HashMap<>();
payload.put("sub", "1234567890");//性为sub,名为123456789
payload.put("name","John Doe");//性为name,名为John Doe
payload.put("admin",true);//性为admin,名为true
String sign = JWT.create()
.withPayload(payload)//负载
.sign(algorithm);
System.out.println(sign);
}
成果打印出来了!!!