Java出现:JWT strings must contain exactly 2 period characters. Found: 0的常见原因及解决方案

 更新时间:2026年01月09日 10:08:31   作者:hellotutu  
这篇文章主要介绍了JWT令牌解析失败的原因和解决方法,包括Header、Payload和Signature三段式结构,常见错误原因,通用解决方案以及额外注意点,需要的朋友可以参考下

这个错误的核心是:你传入的JWT令牌字符串没有包含必需的2个英文句点(.),导致JWT解析器无法按标准拆分令牌结构

一、先理解JWT的标准结构

合法的JWT令牌必须是 Header.Payload.Signature 三段式结构(包含2个句点),例如:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
  • 第一段:Header(Base64编码)
  • 第二段:Payload(Base64编码)
  • 第三段:Signature(签名)
  • 段与段之间用英文句点 . 分隔

二、错误的常见原因(按优先级排查)

1. 传入的令牌为空/空白字符串

  • 现象:前端未传递token、后端接收时为空,或token被误置为空字符串("")。
  • 排查:
// 解析前先校验token是否为空
String token = request.getHeader("Authorization");
if (token == null || token.trim().isEmpty()) {
    throw new IllegalArgumentException("JWT令牌不能为空");
}
// 若用Bearer Token,需先截取(例如:Bearer <token>)
if (token.startsWith("Bearer ")) {
    token = token.substring(7).trim(); // 去掉"Bearer "前缀
}

2. 令牌被截断/拼接错误

  • 现象:token传递过程中被截断(如URL编码/解码错误、字符长度限制),或拼接时丢失句点。
  • 排查:
    • 打印原始token值,确认是否完整(例如:System.out.println("原始token:" + token));
    • 检查前端传递时是否对token做了不必要的转义(如把 . 转成 %2E 但后端未解码)。

3. 令牌格式错误(非JWT)

  • 现象:传入的不是JWT令牌,而是普通字符串、SessionID、其他格式的token(如只有一段/一段半)。
  • 排查:
    • 确认生成token的代码是否正确(例如:使用JJWT/Java JWT库生成时,是否完整调用了签名步骤);
    • 示例:正确生成JWT(以JJWT为例):
// 正确生成三段式JWT
String jwt = Jwts.builder()
    .setHeaderParam("alg", "HS256")
    .setSubject("user123")
    .signWith(SignatureAlgorithm.HS256, "secretKey")
    .compact(); // compact()会生成标准的Header.Payload.Signature结构

4. 令牌被篡改/手动修改

  • 现象:token被人为删除句点,或传输中被篡改(如空格替换句点)。
  • 排查:校验token的字符组成,确保仅包含Base64URL合法字符(字母、数字、-_.)。

三、通用解决方案(解析前增加校验)

在解析JWT前,先校验token的格式合法性,避免直接抛出异常:

import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;

public String parseJwt(String token) {
    // 第一步:校验非空+句点数量
    if (token == null || token.trim().isEmpty()) {
        throw new IllegalArgumentException("JWT令牌不能为空");
    }
    int dotCount = token.length() - token.replace(".", "").length();
    if (dotCount != 2) {
        throw new IllegalArgumentException("JWT令牌格式错误,必须包含2个句点(.),当前数量:" + dotCount);
    }
    
    // 第二步:解析JWT(示例)
    try {
        return Jwts.parser()
            .setSigningKey("secretKey")
            .parseClaimsJws(token)
            .getBody()
            .getSubject();
    } catch (JwtException e) {
        throw new RuntimeException("JWT解析失败:" + e.getMessage());
    }
}

四、额外注意点

  1. Bearer Token前缀:前端传递的token常带 Bearer 前缀(如 Bearer eyJhbGciOiJIUzI1Ni...),需先截取掉前缀再解析;
  2. Base64URL编码:JWT的段使用Base64URL编码(区别于普通Base64),若手动解码需注意替换字符(+-/_,去掉末尾=);
  3. 框架自动解析:若使用Spring Security OAuth2等框架,需确认配置的token提取器是否正确(如从Header/参数中提取)。

快速定位技巧

在解析代码前添加日志,打印原始token值:

System.out.println("待解析的JWT令牌:[" + token + "]");

通过日志可直接判断:

  • 若打印 [] → token为空;
  • 若打印 [eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9] → 只有一段(缺少2个句点);
  • 若打印 [eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkw] → 只有1个句点(缺少1个)。

到此这篇关于Java出现:JWT strings must contain exactly 2 period characters. Found: 0的常见原因及解决方案的文章就介绍到这了,更多相关Java出现:characters. Found: 0内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java 反射机制详解及实例代码

    Java 反射机制详解及实例代码

    本文主要介绍Java 反射机制的知识,这里提供示例代码帮助大家学习理解此部分知识,有需要的小伙伴可以参考下
    2016-09-09
  • java开发RocketMQ生产者高可用示例详解

    java开发RocketMQ生产者高可用示例详解

    这篇文章主要为大家介绍了java开发RocketMQ生产者高可用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Spring Boot Async异步执行任务过程详解

    Spring Boot Async异步执行任务过程详解

    这篇文章主要介绍了Spring Boot Async异步执行任务过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • SpringBoot 回滚操作的几种实现方式

    SpringBoot 回滚操作的几种实现方式

    回滚操作是一种常见的操作,用于撤销之前执行的操作,本文主要介绍了SpringBoot回滚操作的几种实现方式,包含基于异常类型的回滚、基于自定义逻辑的回滚和基于数据库状态的回滚,感兴趣的可以了解一下
    2024-03-03
  • 如何在springboot中实现页面的国际化

    如何在springboot中实现页面的国际化

    今天带大家学习如何在springboot中实现页面的国际化,文中有非常详细的图文解说及代码示例,对正在学习java的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-05-05
  • java基础学习JVM中GC的算法

    java基础学习JVM中GC的算法

    这篇文章主要介绍了java基础学习JVM中GC的算法,通过图文加深对GC算法思路的理解。
    2017-11-11
  • 如何在JDK 9中更简洁使用 try-with-resources 语句

    如何在JDK 9中更简洁使用 try-with-resources 语句

    本文详细介绍了自 JDK 7 引入的 try-with-resources 语句的原理和用法,以及介绍了 JDK 9 对 try-with-resources 的改进,使得用户可以更加方便、简洁的使用 try-with-resources 语句。,需要的朋友可以参考下
    2019-06-06
  • Java线程池的简单使用方法实例教程

    Java线程池的简单使用方法实例教程

    线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的,在jdk1.5之后这一情况有了很大的改,这篇文章主要给大家介绍了关于Java线程池的简单使用方法,需要的朋友可以参考下
    2021-10-10
  • SpringBoot添加Email发送功能及常见异常详解

    SpringBoot添加Email发送功能及常见异常详解

    本篇文章主要介绍了SpringBoot添加Email发送功能及常见异常详解,具有一定的参考价值,有兴趣的可以了解一下。
    2017-04-04
  • Maven中jar包冲突原理与解决办法

    Maven中jar包冲突原理与解决办法

    这篇文章主要介绍了Maven中jar包冲突原理与解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09

最新评论