【 Java 21 使用 JJWT 0.13.0的最新用法】
基于 JJWT 0.13.0 API 的正确代码示例和 Maven 依赖。
确认 Maven 依赖
首先,请确保你的 pom.xml 中使用了正确的依赖配置。从 JJWT 0.13.0 版本开始,库采用了模块化架构。
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.13.0</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.13.0</version><scope>runtime</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred --><version>0.13.0</version><scope>runtime</scope></dependency>
重要提示:根据我查到的信息,0.13.0 版本相关信息出现在一个依赖更新日志中,但主流的文档和示例大多围绕 0.11.x 版本展开。在 0.11.5 版本中,Jwts.parserBuilder() 已是官方推荐的用法。如果你确实需要使用 0.13.0,其核心 API 应与 0.11.x 版本保持一致,但建议你查阅其官方发布说明以确认是否有进一步的变更。
使用新 API 的 JWT 工具类
以下是一个基于你要求的、使用了最新 parserBuilder() API 的 JWT 工具类示例。
public class SecurityProperties { private JwtConfig jwt = new JwtConfig(); /*** JWT密钥 - 至少32字节(256位)用于HMAC-SHA算法*/private String secret;/*** JWT过期时间(秒)*/private Long expiration = 86400L;/*** JWT刷新过期时间(秒)*/private Long refreshExpiration = 604800L;/*** JWT签发者*/private String issuer = "you-system";/*** JWT受众*/private String audience = "you-client";/*** JWT令牌前缀*/private String tokenPrefix = "Bearer";}}
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import javax.crypto.SecretKey;
import java.util.Date;
import java.util.Map;public class JwtUtil {private final SecretKey secretKey;private final long expirationMs;public JwtUtil(SecretKey secretKey, long expirationMs) {this.secretKey = secretKey;this.expirationMs = expirationMs;}/*** 生成JWT令牌** @param subject 主题(如用户ID)* @param claims 自定义声明(载荷)* @return 生成的JWT字符串*/public String generateToken(String subject, Map<String, Object> claims) {long nowMillis = System.currentTimeMillis();Date now = new Date(nowMillis);Date exp = new Date(nowMillis + expirationMs);// 过期方法// JwtBuilder builder = Jwts.builder()// .setSubject(subject)// .setIssuedAt(now)// .setExpiration(exp)// .signWith(secretKey); // 直接使用SecretKey对象String refreshTokenIssuer = securityProperties.getJwt().getIssuer() + "-refresh";// 替换方法JwtBuilder builder = Jwts.builder().claims(claims).subject(subject).issuedAt(toDate(now)).expiration(toDate(expirationTime)).issuer(refreshTokenIssuer) // 设置刷新令牌签发者.audience().add(securityProperties.getJwt().getAudience()).and() // 使用配置的受众.signWith(getSecretKey(), Jwts.SIG.HS512); // 使用HS512算法签名if (claims != null) {builder.setClaims(claims);}// 压缩生成最终令牌return builder.compact();}/*** 解析并验证JWT令牌(使用新API Jwts.parserBuilder())** @param token 待解析的JWT字符串* @return 解析出的声明(Claims)* @throws JwtException 如果令牌无效、过期或签名验证失败*/public Claims parseToken(String token) throws JwtException {// 过时方法// return Jwts.parserBuilder() // 使用新的parserBuilder// .setSigningKey(secretKey) // 设置签名密钥// .build() // 构建不可变的、线程安全的JwtParser实例// .parseClaimsJws(token) // 解析并验证JWT// .getBody(); // 获取载荷(Claims)// 替换方法return Jwts.parser().verifyWith(getSecretKey()).build().parseSignedClaims(token).getPayload();}
}
🔑 密钥生成与管理
在上述工具类中,我们使用了 javax.crypto.SecretKey 对象。你可以使用 JJWT 提供的便捷工具类来生成安全的密钥:
import io.jsonwebtoken.security.Keys;
import javax.crypto.SecretKey;
import java.util.Base64;public class KeyGenerator {public static void main(String[] args) {// 为HS256算法生成一个安全的密钥 SignatureAlgorithm.HS256 过时替换 Jwts.SIG.HS512SecretKey key = Keys.secretKeyFor(Jwts.SIG.HS512);// 如果需要将密钥以字符串形式保存(如存储在配置文件中),可以编码为Base64String base64Key = Base64.getEncoder().encodeToString(key.getEncoded());System.out.println("Base64 encoded key: " + base64Key);// 在应用启动时,可以从Base64字符串重新构造SecretKey// byte[] decodedKey = Base64.getDecoder().decode(base64Key);// SecretKey originalKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "HmacSHA256");}
}
安全提醒:生产环境中,密钥必须妥善保管,严禁硬编码在代码中。建议从安全的配置源(如环境变量、密钥管理服务)获取。
🛠️ 如何使用工具类
初始化工具类并生成、解析令牌的示例:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.security.Keys;
import javax.crypto.SecretKey;
import java.util.HashMap;
import java.util.Map;public class Application {public static void main(String[] args) {// 1. 生成密钥(在实际应用中,这个密钥应该来自安全配置)SecretKey secretKey = Keys.secretKeyFor(Jwts.SIG.HS512);long expirationMs = 24 * 60 * 60 * 1000; // 24小时// 2. 初始化JWT工具类JwtUtil jwtUtil = new JwtUtil(secretKey, expirationMs);// 3. 准备自定义声明Map<String, Object> claims = new HashMap<>();claims.put("userId", 1001);claims.put("role", "admin");// 4. 生成JWT令牌String subject = "user123";String jwtToken = jwtUtil.generateToken(subject, claims);System.out.println("Generated JWT: " + jwtToken);// 5. 解析和验证JWT令牌try {Claims parsedClaims = jwtUtil.parseToken(jwtToken);System.out.println("Token subject: " + parsedClaims.getSubject());System.out.println("User ID from token: " + parsedClaims.get("userId", Integer.class));} catch (JwtException e) {System.err.println("JWT validation failed: " + e.getMessage());}}
}
💎 核心变更与总结
- 主要变更:新的
JwtParser实例是不可变且线程安全的。 - 密钥安全:推荐使用
io.jsonwebtoken.security.Keys工具类生成安全的SecretKey对象,而不是直接使用字符串。 - 依赖模块化:确保你的依赖配置正确,引入了
jjwt-api、jjwt-impl和jjwt-jackson(或jjwt-gson)。
希望这个基于最新 API 的示例能帮助你顺利完成升级!如果你在密钥管理或者异常处理方面有更多疑问,我很乐意提供进一步的信息。
