<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>zzc-blog</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <icon>https://blog.zzc.dpdns.org/img/butterfly-icon.png</icon>
  <id>https://blog.zzc.dpdns.org/</id>
  <link href="https://blog.zzc.dpdns.org/" rel="alternate"/>
  <link href="https://blog.zzc.dpdns.org/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, zzc-blog</rights>
  <title>zzc-blog</title>
  <updated>2026-07-05T15:18:49.617Z</updated>
  <entry>
    <author>
      <name>zzc-blog</name>
    </author>
    <category term="技术" scheme="https://blog.zzc.dpdns.org/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="数据库" scheme="https://blog.zzc.dpdns.org/categories/%E6%8A%80%E6%9C%AF/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    <category term="MySQL" scheme="https://blog.zzc.dpdns.org/tags/MySQL/"/>
    <content>
      <![CDATA[<h2 id="1-什么是-MySQL"><a href="#1-什么是-MySQL" class="headerlink" title="1. 什么是 MySQL"></a>1. 什么是 MySQL</h2><p><em>MySQL 是最流行的关系型数据库管理系统，在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System：关系数据库管理系统)应用软件之一。</em></p><h2 id="2-安装-MySQL"><a href="#2-安装-MySQL" class="headerlink" title="2. 安装 MySQL"></a>2. 安装 MySQL</h2><h2 id="3-MySQL-高级"><a href="#3-MySQL-高级" class="headerlink" title="3. MySQL 高级"></a>3. MySQL 高级</h2>]]>
    </content>
    <id>https://blog.zzc.dpdns.org/2026/07/05/Mysql%E5%9F%BA%E7%A1%80/</id>
    <link href="https://blog.zzc.dpdns.org/2026/07/05/Mysql%E5%9F%BA%E7%A1%80/"/>
    <published>2026-07-05T11:09:35.000Z</published>
    <summary>
      <![CDATA[<h2 id="1-什么是-MySQL"><a href="#1-什么是-MySQL" class="headerlink" title="1. 什么是 MySQL"></a>1. 什么是 MySQL</h2><p><em>MySQL 是最流行的关系型数据库管理系统，在 WEB]]>
    </summary>
    <title>Mysql基础</title>
    <updated>2026-07-05T15:18:49.617Z</updated>
  </entry>
  <entry>
    <author>
      <name>zzc-blog</name>
    </author>
    <category term="技术" scheme="https://blog.zzc.dpdns.org/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="Java" scheme="https://blog.zzc.dpdns.org/categories/%E6%8A%80%E6%9C%AF/Java/"/>
    <category term="JWT" scheme="https://blog.zzc.dpdns.org/tags/JWT/"/>
    <content>
      <![CDATA[<h2 id="1-什么是-JWT"><a href="#1-什么是-JWT" class="headerlink" title="1. 什么是 JWT"></a>1. 什么是 JWT</h2><p><code>JWT</code>（JSON Web Token）是一种基于<code>JSON</code>的开放标准（RFC 7519），用于在各方之间以紧凑且自包含的方式安全传输信息。它通常用于身份认证和信息交换，由三部分组成：<code>Header</code>（头部）、<code>Payload</code>（载荷）和 <code>Signature</code>（签名），格式为 <code>xxxxx.yyyyy.zzzzz</code>。</p><h2 id="2-使用-JWT"><a href="#2-使用-JWT" class="headerlink" title="2. 使用 JWT"></a>2. 使用 JWT</h2><p>下面从依赖引入开始，逐步搭建 JWT 工具类。</p><h3 id="2-1-引入依赖"><a href="#2-1-引入依赖" class="headerlink" title="2.1 引入依赖"></a>2.1 引入依赖</h3><blockquote><p><strong>JJWT 版本差异说明</strong>：</p><ul><li><p><strong>0.9.1 及更早版本</strong>：<code>io.jsonwebtoken:jjwt</code>（一个 jar 包）</p></li><li><p>0.10.0 及更高版本（特别是 0.11.x 及更高版本）</p><p>：模块化方法</p><ul><li><code>jjwt-api</code>（编译期）</li><li><code>jjwt-impl</code>（运行时，通常为 <code>runtime</code> 作用域）</li><li><code>jjwt-jackson</code>（JSON 序列化&#x2F;反序列化，<code>runtime</code> 作用域）</li></ul></li></ul><p>关键区别：0.10+ 使用 <code>javax.xml.bind</code>（较旧）或 <code>java.base</code>（较新），但更重要的模块化是必需的。</p></blockquote><p>依赖</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">properties</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">jjwt.version</span>&gt;</span>0.12.6<span class="tag">&lt;/<span class="name">jjwt.version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">properties</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 1. 核心API（编译期需要） --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>io.jsonwebtoken<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>jjwt-api<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;jjwt.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!-- 2. 运行时实现（必须） --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>io.jsonwebtoken<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>jjwt-impl<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;jjwt.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">scope</span>&gt;</span>runtime<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!-- 3. Jackson序列化支持（建议保留，否则操作复杂对象会报错） --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>io.jsonwebtoken<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>jjwt-jackson<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;jjwt.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">scope</span>&gt;</span>runtime<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="2-2-依赖说明"><a href="#2-2-依赖说明" class="headerlink" title="2.2 依赖说明"></a>2.2 依赖说明</h3><ol><li><strong>jjwt-api（必须保留）</strong></li></ol><p>  <strong>作用</strong>：编译期需要的接口和注解（如 <code>Jwts.builder()</code>、<code>Claims</code> 等）。</p><p>  <strong>能否省略</strong>：绝对不能。没有它，你的代码连 <code>import</code> 都编译不过。</p><ol start="2"><li><strong>jjwt-impl（必须保留）</strong></li></ol><p>  <strong>作用</strong>：运行时的具体实现类（真正的签名、加密 算法逻辑）。</p><p>  <strong>能否省略</strong>：绝对不能。没有它，运行时会报 <code>NoClassDefFoundError</code> 或 <code>NoSuchMethodError</code>。注意它设置了 <code>&lt;scope&gt;runtime&lt;/scope&gt;</code>，这很合理，因为编译期只需要接口（api），运行期才需要实现。</p><ol start="3"><li><strong>jjwt-jackson（强烈建议保留）</strong></li></ol><p>  <strong>作用</strong>：负责 JWT 中 Payload（载荷&#x2F;Claims）的 JSON 序列化和反序列化。</p><p>  <strong>能否省略</strong>：视情况而定，但 99% 的情况下建议保留。</p><ul><li><p>如果你的 Claims 里只放字符串、数字（如 <code>userId</code>、<code>role</code>），去掉它暂时能跑（JJWT 内部会尝试用简单解析器处理）。</p></li><li><p>但只要你往 Claims 里放一个自定义对象（POJO），或者取出来时想直接转成对象，去掉它立马报序列化异常。</p><p><strong>最佳实践</strong>：为了防止项目迭代时踩坑，直接带上它，成本极低。</p></li></ul><h3 id="2-3-代码示例"><a href="#2-3-代码示例" class="headerlink" title="2.3 代码示例"></a>2.3 代码示例</h3><p>载荷</p><p><img src="https://hexo-1304867193.cos.ap-guangzhou.myqcloud.com/images/image-20260705183318753.png" alt="image-20260705183318753"></p><p><img src="https://hexo-1304867193.cos.ap-guangzhou.myqcloud.com/images/image-20260705183359395.png" alt="image-20260705183359395"></p><p><img src="https://hexo-1304867193.cos.ap-guangzhou.myqcloud.com/images/image-20260705183415020.png" alt="image-20260705183415020"></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> io.jsonwebtoken.Jwts;</span><br><span class="line"><span class="keyword">import</span> io.jsonwebtoken.security.Keys;</span><br><span class="line"><span class="keyword">import</span> javax.crypto.SecretKey;</span><br><span class="line"><span class="keyword">import</span> java.nio.charset.StandardCharsets;</span><br><span class="line"><span class="keyword">import</span> java.util.Date;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">JwtUtils</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 新版本要求密钥长度：HS256 必须 &gt;= 256位（32个字符），否则启动报错</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">APP_SECRET</span> <span class="operator">=</span> <span class="string">&quot;yourSecretKeyYourSecretKeyYourSecretKey!&quot;</span>; <span class="comment">// 至少32位</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">EXPIRE</span> <span class="operator">=</span> <span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 生成密钥对象（新API写法）</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> SecretKey <span class="title function_">getKey</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> Keys.hmacShaKeyFor(APP_SECRET.getBytes(StandardCharsets.UTF_8));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 1. 生成JWT（新API链式调用）</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">generateToken</span><span class="params">(String userId, String role)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> Jwts.builder()</span><br><span class="line">                .subject(userId) <span class="comment">// 对应 setSubject</span></span><br><span class="line">                .claim(<span class="string">&quot;role&quot;</span>, role)</span><br><span class="line">                .issuedAt(<span class="keyword">new</span> <span class="title class_">Date</span>()) <span class="comment">// 对应 setIssuedAt</span></span><br><span class="line">                .expiration(<span class="keyword">new</span> <span class="title class_">Date</span>(System.currentTimeMillis() + EXPIRE)) <span class="comment">// 对应 setExpiration</span></span><br><span class="line">                .signWith(getKey()) <span class="comment">// 新API：直接传 SecretKey 对象，无需指定算法（自动推断）</span></span><br><span class="line">                .compact();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 2. 解析JWT（新API写法，捕获异常来校验）</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> Claims <span class="title function_">checkJWT</span><span class="params">(String token)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> Jwts.parser()</span><br><span class="line">                    .verifyWith(getKey()) <span class="comment">// 新API：验证密钥</span></span><br><span class="line">                    .build()</span><br><span class="line">                    .parseSignedClaims(token) <span class="comment">// 新API：解析签名Claims</span></span><br><span class="line">                    .getPayload(); <span class="comment">// 获取载荷</span></span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            <span class="comment">// 过期或签名错误</span></span><br><span class="line">            <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="生成端逐行拆解"><a href="#生成端逐行拆解" class="headerlink" title="生成端逐行拆解"></a>生成端逐行拆解</h3><p>整个过程可以拆解为 <strong>“装数据 → 设时间 → 加签名 → 打包输出”</strong> 四个步骤：</p><p><strong>1. <code>Jwts.builder()</code> —— 开工</strong><br>创建一个空的 JWT 构建器对象，准备往里塞东西。</p><p><strong>2. 数据装载区（谁、是什么）</strong></p><ul><li><code>.subject(userId)</code>：将用户 ID 存入标准字段 <code>sub</code>（Subject），告诉系统”这个令牌代表谁”。</li><li><code>.claim(&quot;role&quot;, role)</code>：存入自定义字段 <code>role</code>，通常用于存角色、权限或用户昵称。</li></ul><p>这两行最终会变成 JWT 载荷（Payload）中的 <code>{&quot;sub&quot;:&quot;10001&quot;, &quot;role&quot;:&quot;admin&quot;}</code>。</p><p><strong>3. 时间控制区（生效与失效）</strong></p><ul><li><code>.issuedAt(new Date())</code>：设置签发时间 <code>iat</code>（Issued At），取当前系统时间，用于记录 Token 何时生成。</li><li><code>.expiration(new Date(System.currentTimeMillis() + EXPIRE))</code>：设置过期时间 <code>exp</code>（Expiration），在当前时间上加上预设时长（如 <code>EXPIRE = 3600000</code> 毫秒即 1 小时），告诉系统”到这个时间点后，Token 就作废”。</li></ul><p><strong>4. 加密签名区（防伪认证）</strong></p><ul><li><code>.signWith(getKey())</code>：使用密钥对头部（Header）和载荷（Payload）进行加密签名。</li></ul><p>在 0.12.x 版本中，无需手动指定算法（如 HS256）。JJWT 会根据你传入的 <code>SecretKey</code> 密钥长度自动选择最强安全的算法（密钥 &gt;&#x3D; 32 字节自动选 HS256）。这一行生成签名，确保 Token 内容不被篡改。只要密钥不泄露，任何人修改了载荷内容，签名校验都会失败。</p><p><strong>5. <code>.compact()</code> —— 打包出厂（终极执行）</strong><br>这是终结操作（Terminal Operation）。它将前三步组装好的头部、载荷进行 Base64Url 编码，然后拼接上签名，最终输出一个用点号（<code>.</code>）分隔的紧凑字符串：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMDAwMSIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTcxODAwMDAwMCwiZXhwIjoxNzE4MDAzNjAwfQ.abc123def456...</span><br></pre></td></tr></table></figure><blockquote><p><strong>⚠️ 特别注意（避坑指南）</strong></p><ul><li><strong>密钥长度</strong>：务必确保密钥字符串长度 &gt;&#x3D; 32 个字符。如果低于 32 位，<code>signWith()</code> 执行时会抛出 <code>WeakKeyException</code> 异常导致生成失败。</li><li><strong><code>compact()</code> 只能调用一次</strong>：构建器在调用 <code>compact()</code> 后即被”消费”，无法再次修改或重新生成。如果后续想调整过期时间，必须重新调用 <code>Jwts.builder()</code> 新建一个对象。</li></ul></blockquote><h3 id="解析端逐行拆解"><a href="#解析端逐行拆解" class="headerlink" title="解析端逐行拆解"></a>解析端逐行拆解</h3><p>生成是这一套，解析时就是反向操作：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 解析时，用 verifyWith(getKey()) 替换 signWith()</span></span><br><span class="line">Jwts.parser().verifyWith(getKey()).build().parseSignedClaims(token).getPayload();</span><br></pre></td></tr></table></figure><p><strong>1. <code>Jwts.parser()</code> —— 启动解析器</strong><br>创建一个 JWT 解析器的构建器实例，准备开始读取和校验 Token 字符串。</p><p><strong>2. <code>.verifyWith(getKey())</code> —— 设置验钞机模板（核心防伪）</strong><br>传入与生成时完全相同的密钥，用于校验 Token 的签名（Signature）。JJWT 会拿这个密钥，对当前 Token 的头部（Header）和载荷（Payload）重新计算一次签名，然后与 Token 自带的签名进行比对：</p><ul><li><strong>一致</strong>：说明内容没被篡改，且确实是由我们的服务端签发的。</li><li><strong>不一致</strong>：说明 Token 被篡改或伪造，后续解析会报错。</li></ul><blockquote><p>注：新版本 API 已废弃旧版的 <code>setSigningKey()</code>，强制使用 <code>verifyWith()</code>，语义更明确（专门用于验证）。</p></blockquote><p><strong>3. <code>.build()</code> —— 组装验钞机</strong><br>将前面设置的密钥等配置”固化”成一个不可变的解析器实例。这一步只是准备，尚未开始实际解析。</p><p><strong>4. <code>.parseSignedClaims(token)</code> —— 拆信封并验真伪（最关键的触发点）</strong><br>这是真正干活的一行，内部会按顺序做三件大事：</p><ul><li><strong>解码</strong>：将 JWT 字符串按 <code>.</code> 分割，分别解码 Header 和 Payload。</li><li><strong>验签（安全校验）</strong>：立即执行签名比对。如果签名无效，直接抛出 <code>SignatureException</code>。</li><li><strong>校验时效（时间门禁）</strong>：自动检查载荷中的 <code>exp</code>（过期时间）和 <code>iat</code>（签发时间）。如果当前系统时间晚于 <code>exp</code>，抛出 <code>ExpiredJwtException</code>（令牌过期）。（如果设置了 <code>nbf</code> 不早于时间，也会在此检查。）</li></ul><p>如果以上任何一步失败，整行代码都会抛出异常，程序会直接跳转到你的 <code>catch</code> 块中。</p><p><strong>5. <code>.getPayload()</code> —— 读取信纸内容（获取数据）</strong><br>一旦过了上面那道”安检门”，这行代码就很简单了：直接返回载荷（Payload）中的 <code>Claims</code> 对象（可以理解为一个 Map&#x2F;字典）。拿到这个 <code>Claims</code> 后，就可以通过 <code>.getSubject()</code> 或 <code>.get(&quot;role&quot;)</code> 来读取之前存入的用户 ID 和角色信息了。</p><h3 id="生成-vs-解析对照表"><a href="#生成-vs-解析对照表" class="headerlink" title="生成 vs 解析对照表"></a>生成 vs 解析对照表</h3><table><thead><tr><th>阶段</th><th>生成（Builder）</th><th>解析（Parser）</th></tr></thead><tbody><tr><td>准备密钥</td><td><code>.signWith(getKey())</code> 用于签名</td><td><code>.verifyWith(getKey())</code> 用于验签</td></tr><tr><td>动作触发</td><td><code>.compact()</code> 打包输出字符串</td><td><code>.parseSignedClaims(token)</code> 拆包并核验</td></tr><tr><td>异常时机</td><td>仅在密钥太短时会报错</td><td>高频报错区：过期、篡改、格式错误都发生在这一行</td></tr><tr><td>结果</td><td>返回紧凑的 JWT 字符串</td><td>返回安全的 Claims 对象</td></tr></tbody></table><h3 id="特别注意（一定要记住）"><a href="#特别注意（一定要记住）" class="headerlink" title="特别注意（一定要记住）"></a>特别注意（一定要记住）</h3><p><strong>1. <code>verifyWith</code> 必须和 <code>signWith</code> 密钥相同</strong><br>这一点至关重要。一个密钥负责”签封”，另一个必须用完全相同的密钥来”拆封”，否则验签必失败。</p><p><strong>2. 异常处理必须精确</strong><br>因为 <code>.parseSignedClaims(token)</code> 会抛出多种异常，在实际项目中，强烈建议在 <code>catch</code> 块中区分异常类型，以便给前端返回不同的提示：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> Jwts.parser().verifyWith(getKey()).build().parseSignedClaims(token).getPayload();</span><br><span class="line">&#125; <span class="keyword">catch</span> (ExpiredJwtException e) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(<span class="string">&quot;登录已过期，请重新登录&quot;</span>);</span><br><span class="line">&#125; <span class="keyword">catch</span> (MalformedJwtException | SignatureException e) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(<span class="string">&quot;无效的Token，请重新登录&quot;</span>);</span><br><span class="line">&#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(<span class="string">&quot;认证失败&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><hr><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><ul><li><strong>三个依赖都加，别省</strong>，否则以后放复杂对象时排查问题很痛苦。</li><li><strong>代码别抄旧版的</strong>，用上面新版的 <code>signWith(getKey())</code> 和 <code>verifyWith(getKey())</code> 写法。</li><li><strong>确保版本号已定义</strong>：<code>jjwt.version</code> 属性值在 <code>pom.xml</code> 里定义了（比如 <code>&lt;jjwt.version&gt;0.12.6&lt;/jjwt.version&gt;</code>）。</li><li><strong>密钥长度要达标</strong>：密钥字符串长度至少 32 个字符，否则启动会报 <code>WeakKeyException</code>。</li><li><strong>Jackson 兼容性</strong>：如果你的项目里本来就有 Jackson（<code>spring-boot-starter-web</code> 自带了），<code>jjwt-jackson</code> 会和它自动配合，开箱即用。</li></ul>]]>
    </content>
    <id>https://blog.zzc.dpdns.org/2026/07/05/JWT%E5%8F%8A%E5%85%B6%E4%BD%BF%E7%94%A8/</id>
    <link href="https://blog.zzc.dpdns.org/2026/07/05/JWT%E5%8F%8A%E5%85%B6%E4%BD%BF%E7%94%A8/"/>
    <published>2026-07-05T10:24:30.000Z</published>
    <summary>
      <![CDATA[<h2 id="1-什么是-JWT"><a href="#1-什么是-JWT" class="headerlink" title="1. 什么是 JWT"></a>1. 什么是 JWT</h2><p><code>JWT</code>（JSON Web]]>
    </summary>
    <title>JWT及其使用</title>
    <updated>2026-07-05T15:18:49.617Z</updated>
  </entry>
  <entry>
    <author>
      <name>zzc-blog</name>
    </author>
    <category term="技术" scheme="https://blog.zzc.dpdns.org/categories/%E6%8A%80%E6%9C%AF/"/>
    <category term="Java" scheme="https://blog.zzc.dpdns.org/categories/%E6%8A%80%E6%9C%AF/Java/"/>
    <category term="JVM" scheme="https://blog.zzc.dpdns.org/tags/JVM/"/>
    <category term="Java" scheme="https://blog.zzc.dpdns.org/tags/Java/"/>
    <category term="JVM原理" scheme="https://blog.zzc.dpdns.org/tags/JVM%E5%8E%9F%E7%90%86/"/>
    <category term="内存管理" scheme="https://blog.zzc.dpdns.org/tags/%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/"/>
    <content>
      <![CDATA[<h2 id="1-什么是JVM"><a href="#1-什么是JVM" class="headerlink" title="1. 什么是JVM"></a>1. 什么是JVM</h2><p><img src="https://hexo-1304867193.cos.ap-guangzhou.myqcloud.com/images/image-20260705145041732.png" alt="image-20260705145041732"></p><h2 id="2-运行时数据区"><a href="#2-运行时数据区" class="headerlink" title="2. 运行时数据区"></a>2. 运行时数据区</h2><h3 id="1-程序计数器"><a href="#1-程序计数器" class="headerlink" title="1. 程序计数器"></a>1. 程序计数器</h3><p><img src="https://hexo-1304867193.cos.ap-guangzhou.myqcloud.com/images/image-20260705145052850.png" alt="image-20260705145052850"></p><h3 id="2-JVM-栈"><a href="#2-JVM-栈" class="headerlink" title="2. JVM 栈"></a>2. JVM 栈</h3><p><img src="https://hexo-1304867193.cos.ap-guangzhou.myqcloud.com/images/image-20260705145102783.png" alt="image-20260705145102783"></p><h3 id="3-堆"><a href="#3-堆" class="headerlink" title="3. 堆"></a>3. 堆</h3><p><img src="https://hexo-1304867193.cos.ap-guangzhou.myqcloud.com/images/image-20260705145114131.png" alt="image-20260705145114131"></p>]]>
    </content>
    <id>https://blog.zzc.dpdns.org/2026/07/05/JVM%E5%AD%A6%E4%B9%A0/</id>
    <link href="https://blog.zzc.dpdns.org/2026/07/05/JVM%E5%AD%A6%E4%B9%A0/"/>
    <published>2026-07-05T06:34:24.000Z</published>
    <summary>
      <![CDATA[<h2 id="1-什么是JVM"><a href="#1-什么是JVM" class="headerlink" title="1. 什么是JVM"></a>1. 什么是JVM</h2><p><img]]>
    </summary>
    <title>JVM学习</title>
    <updated>2026-07-05T15:18:49.617Z</updated>
  </entry>
</feed>
