<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>kil-Blog</title>
    <link>https://b.122345.xyz/</link>
    
    <atom:link href="https://b.122345.xyz/rss2.xml" rel="self" type="application/rss+xml"/>
    
    <description>技术分享和生活记录</description>
    <pubDate>Sun, 19 Jan 2025 14:58:21 GMT</pubDate>
    <generator>http://hexo.io/</generator>
    
    <item>
      <title>Node.js 创建一个简单的服务实现反向代理</title>
      <link>https://b.122345.xyz/2024/07/09/Node-js-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/</link>
      <guid>https://b.122345.xyz/2024/07/09/Node-js-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/</guid>
      <pubDate>Tue, 09 Jul 2024 07:13:20 GMT</pubDate>
      
        
        
      <description>&lt;h2 id=&quot;创建一个Node-js项目&quot;&gt;&lt;a href=&quot;#创建一个Node-js项目&quot; class=&quot;headerlink&quot; title=&quot;创建一个Node.js项目&quot;&gt;&lt;/a&gt;创建一个Node.js项目&lt;/h2&gt;&lt;p&gt;打开文件管理器，在你想要的索引位置上新建一个文件夹，</description>
        
      
      
      
      <content:encoded><![CDATA[<h2 id="创建一个Node-js项目"><a href="#创建一个Node-js项目" class="headerlink" title="创建一个Node.js项目"></a>创建一个Node.js项目</h2><p>打开文件管理器，在你想要的索引位置上新建一个文件夹，文件夹的名称即是项目名</p><p>用Visual Studio Code打开这个文件夹，并在终端执行</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm init</span><br></pre></td></tr></table></figure><img src="/2024/07/09/Node-js-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/264e1d9aaf5d6963cd5c03f7174a2e4b.png" class="" title="图片[1]-Node.js 创建一个简单的服务实现反向代理-TOY论坛"><p>没有特定要求一直回车即可，也可参考其他Node.js项目教程</p><h2 id="安装所需依赖"><a href="#安装所需依赖" class="headerlink" title="安装所需依赖"></a>安装所需依赖</h2><p>安装http-proxy-middleware</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install http-proxy-middleware</span><br></pre></td></tr></table></figure><h2 id="导入代码"><a href="#导入代码" class="headerlink" title="导入代码"></a>导入代码</h2><ul><li>新建一个index.js，为主要执行程序</li><li>新建一个api文件夹，并在api文件下新建module.js。用于不走代理时执行自定义代码</li></ul><p>index.js</p><figure class="highlight js"><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><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> http = <span class="built_in">require</span>(<span class="string">&#x27;http&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> &#123; createProxyMiddleware &#125; = <span class="built_in">require</span>(<span class="string">&#x27;http-proxy-middleware&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> printStr = <span class="built_in">require</span>(<span class="string">&#x27;./api/module&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">&#x27;fs&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> newProxy = <span class="title function_">createProxyMiddleware</span>(&#123;</span><br><span class="line">    <span class="attr">target</span>: <span class="string">&#x27;https://www.baidu.com&#x27;</span>,</span><br><span class="line">    <span class="attr">changeOrigin</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">pathRewrite</span>: &#123;</span><br><span class="line">        <span class="string">&#x27;^/proxy&#x27;</span>: <span class="string">&#x27;&#x27;</span>, <span class="comment">// 将路径中的 &#x27;/proxy&#x27; 替换为空字符串</span></span><br><span class="line">        <span class="string">&#x27;^/&#x27;</span>: <span class="string">&#x27;&#x27;</span>, <span class="comment">// 将路径中的 &#x27;/&#x27; 替换为空字符串</span></span><br><span class="line">    &#125;,</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> server = http.<span class="title function_">createServer</span>(<span class="function">(<span class="params">req, res</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">const</span> clientIp = req.<span class="property">socket</span>.<span class="property">remoteAddress</span>;</span><br><span class="line">    <span class="comment">// 检查请求路径，如果是以 &#x27;/noproxy&#x27; 开头，则不进行代理</span></span><br><span class="line">    <span class="keyword">if</span> (req.<span class="property">url</span>.<span class="title function_">startsWith</span>(<span class="string">&#x27;/noproxy&#x27;</span>)) &#123;</span><br><span class="line">        <span class="comment">//判断是否为POST请求</span></span><br><span class="line">        <span class="keyword">if</span> (req.<span class="property">method</span> === <span class="string">&#x27;POST&#x27;</span>) &#123;</span><br><span class="line">            <span class="keyword">let</span> body = <span class="string">&#x27;&#x27;</span>;</span><br><span class="line">            <span class="comment">// 方法: on() 方法用于监听事件，第一个参数是事件名称，这里是 &#x27;data&#x27;，表示接收到请求体数据时触发。</span></span><br><span class="line">            <span class="comment">// chunk 参数: 在 &#x27;data&#x27; 事件中，回调函数被调用多次，每次传递一个数据块 chunk。这些数据块通常是Buffer对象，表示来自客户端的一部分数据。</span></span><br><span class="line">            req.<span class="title function_">on</span>(<span class="string">&#x27;data&#x27;</span>, <span class="function">(<span class="params">chunk</span>) =&gt;</span> &#123;</span><br><span class="line">                <span class="comment">// chunk.toString(): 将每个数据块 chunk 转换为字符串形式。因为HTTP请求体可以是任何类型的数据，例如表单数据或JSON数据，因此需要将每个数据块转换为字符串进行处理。</span></span><br><span class="line">                body += chunk.<span class="title function_">toString</span>(); <span class="comment">// 这行代码将每个接收到的数据块字符串拼接到 body 变量中。这样，当所有数据块都接收完毕时，body 将包含完整的请求体数据。</span></span><br><span class="line">            &#125;);</span><br><span class="line">            <span class="comment">// 这里是 &#x27;end&#x27;，表示请求数据接收完毕时触发。</span></span><br><span class="line">            req.<span class="title function_">on</span>(<span class="string">&#x27;end&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">                <span class="comment">// 解析 POST 请求参数</span></span><br><span class="line">                <span class="keyword">const</span> postData = <span class="title class_">JSON</span>.<span class="title function_">parse</span>(body);</span><br><span class="line">                <span class="keyword">const</span> &#123; domain &#125; = postData;</span><br><span class="line">                <span class="comment">// 判断 domain 参数是否存在</span></span><br><span class="line">                <span class="keyword">if</span> (domain) &#123;</span><br><span class="line">                    <span class="keyword">const</span> jsonData = <span class="title function_">printStr</span>(domain);</span><br><span class="line">                    <span class="comment">// 设置HTTP状态码为200（成功）并将内容类型设置为 application/json。</span></span><br><span class="line">                    res.<span class="title function_">writeHead</span>(<span class="number">200</span>, &#123; <span class="string">&#x27;Content-Type&#x27;</span>: <span class="string">&#x27;application/json&#x27;</span> &#125;);</span><br><span class="line">                    <span class="comment">// 将 jsonData 对象作为JSON字符串发送到响应体中。</span></span><br><span class="line">                    res.<span class="title function_">end</span>(<span class="title class_">JSON</span>.<span class="title function_">stringify</span>(jsonData));</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    <span class="keyword">const</span> jsonData = &#123;</span><br><span class="line">                        <span class="attr">success</span>: <span class="literal">true</span>,</span><br><span class="line">                        <span class="attr">message</span>: <span class="string">&quot;参数不完整&quot;</span>,</span><br><span class="line">                        <span class="attr">code</span>: <span class="number">200</span>,</span><br><span class="line">                        <span class="attr">timestamp</span>: <span class="title class_">Math</span>.<span class="title function_">round</span>(<span class="keyword">new</span> <span class="title class_">Date</span>())</span><br><span class="line">                    &#125;;</span><br><span class="line">                    res.<span class="title function_">writeHead</span>(<span class="number">200</span>, &#123; <span class="string">&#x27;Content-Type&#x27;</span>: <span class="string">&#x27;application/json&#x27;</span> &#125;);</span><br><span class="line">                    res.<span class="title function_">end</span>(<span class="title class_">JSON</span>.<span class="title function_">stringify</span>(jsonData));</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">const</span> jsonData = &#123;</span><br><span class="line">                <span class="attr">success</span>: <span class="literal">true</span>,</span><br><span class="line">                <span class="attr">message</span>: <span class="string">&quot;GET方式请求&quot;</span>,</span><br><span class="line">                <span class="attr">code</span>: <span class="number">200</span>,</span><br><span class="line">                <span class="attr">timestamp</span>: <span class="title class_">Math</span>.<span class="title function_">round</span>(<span class="keyword">new</span> <span class="title class_">Date</span>())</span><br><span class="line">            &#125;;</span><br><span class="line">            res.<span class="title function_">writeHead</span>(<span class="number">200</span>, &#123; <span class="string">&#x27;Content-Type&#x27;</span>: <span class="string">&#x27;application/json&#x27;</span> &#125;);</span><br><span class="line">            res.<span class="title function_">end</span>(<span class="title class_">JSON</span>.<span class="title function_">stringify</span>(jsonData));</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="comment">// 检查请求路径，如果是以 &#x27;/proxy&#x27; 开头，则进行代理</span></span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (req.<span class="property">url</span>.<span class="title function_">startsWith</span>(<span class="string">&#x27;/proxy&#x27;</span>)) &#123;</span><br><span class="line">        <span class="comment">// 执行newProxy代理</span></span><br><span class="line">        <span class="title function_">newProxy</span>(req, res);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="title function_">sendPage</span>(<span class="string">&#x27;./page/404.html&#x27;</span>, res);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">getClientIp</span>(<span class="params">req</span>) &#123;</span><br><span class="line">    <span class="keyword">const</span> xForwardedFor = req.<span class="property">headers</span>[<span class="string">&#x27;x-forwarded-for&#x27;</span>];</span><br><span class="line">    <span class="keyword">if</span> (xForwardedFor) &#123;</span><br><span class="line">        <span class="keyword">const</span> ipList = xForwardedFor.<span class="title function_">split</span>(<span class="string">&#x27;,&#x27;</span>);</span><br><span class="line">        <span class="keyword">return</span> ipList[ipList.<span class="property">length</span> - <span class="number">1</span>].<span class="title function_">trim</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> req.<span class="property">connection</span>.<span class="property">remoteAddress</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">sendPage</span>(<span class="params">pagePath, res</span>) &#123;</span><br><span class="line">    <span class="comment">// 读取HTML文件</span></span><br><span class="line">    fs.<span class="title function_">readFile</span>(pagePath, <span class="function">(<span class="params">err, data</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (err) &#123;</span><br><span class="line">            res.<span class="title function_">writeHead</span>(<span class="number">404</span>);</span><br><span class="line">            res.<span class="title function_">end</span>(<span class="string">&quot;404 Not Found&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            res.<span class="title function_">writeHead</span>(<span class="number">200</span>, &#123; <span class="string">&#x27;Content-Type&#x27;</span>: <span class="string">&#x27;text/html; charset=utf-8&#x27;</span> &#125;);</span><br><span class="line">            res.<span class="title function_">end</span>(data);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> port = process.<span class="property">env</span>.<span class="property">PORT</span> || <span class="number">3000</span>;</span><br><span class="line">server.<span class="title function_">listen</span>(port, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`Proxy server running on port <span class="subst">$&#123;port&#125;</span>`</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>module.js</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">printStr</span>(<span class="params">domain</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">        <span class="attr">success</span>: <span class="literal">true</span>,</span><br><span class="line">        <span class="attr">message</span>: domain,</span><br><span class="line">        <span class="attr">code</span>: <span class="number">200</span>,</span><br><span class="line">        <span class="attr">timestamp</span>: <span class="title class_">Math</span>.<span class="title function_">round</span>(<span class="keyword">new</span> <span class="title class_">Date</span>())</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = printStr;</span><br></pre></td></tr></table></figure><p>目录结构</p><img src="/2024/07/09/Node-js-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/85eaf7c2f5fc0ab5f73d55bff82df069.png" class="" title="图片[2]-Node.js 创建一个简单的服务实现反向代理-TOY论坛"><h2 id="添加启动程序执行命令"><a href="#添加启动程序执行命令" class="headerlink" title="添加启动程序执行命令"></a>添加启动程序执行命令</h2><p>在package.json文件中的scripts对象中添加start属性</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">&quot;start&quot;</span><span class="punctuation">:</span> <span class="string">&quot;node index.js&quot;</span></span><br></pre></td></tr></table></figure><img src="/2024/07/09/Node-js-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/7fd637bd7eb1e630b301bc7f50a189a0.png" class="" title="图片[3]-Node.js 创建一个简单的服务实现反向代理-TOY论坛"><h2 id="运行"><a href="#运行" class="headerlink" title="运行"></a>运行</h2><p>终端输入</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run start</span><br></pre></td></tr></table></figure><img src="/2024/07/09/Node-js-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/62e7363d8cbe8a8f155f1f8e53664209.png" class="" title="图片[4]-Node.js 创建一个简单的服务实现反向代理-TOY论坛"><h2 id="测试效果"><a href="#测试效果" class="headerlink" title="测试效果"></a>测试效果</h2><p>访问<a href="http://localhost:3000/proxy%E4%BB%A3%E7%90%86%E8%87%B3%E7%99%BE%E5%BA%A6">http://localhost:3000/proxy代理至百度</a></p><img src="/2024/07/09/Node-js-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/c3fa81c95dde1a5531479fd7b6747380-1024x208.png" class="" title="图片[5]-Node.js 创建一个简单的服务实现反向代理-TOY论坛"><p>搜索时要在域名后添加要添加&#x2F;proxy路径，用来检测是否使用代理，代码中会把&#x2F;proxy替换为空字符串</p><img src="/2024/07/09/Node-js-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/b211a1a3d77d54fb5c69535808d81e2b.png" class="" title="图片[6]-Node.js 创建一个简单的服务实现反向代理-TOY论坛"><p>使用post访问<a href="http://localhost:3000/noproxy%EF%BC%8C%E5%B9%B6%E4%BC%A0%E9%80%92json%E5%AF%B9%E8%B1%A1">http://localhost:3000/noproxy，并传递json对象</a></p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;domain&quot;</span><span class="punctuation">:</span> <span class="string">&quot;aaaa&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><img src="/2024/07/09/Node-js-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/13f04818fe8e956f6b0a9df0b6730011-1024x571.png" class="" title="图片[7]-Node.js 创建一个简单的服务实现反向代理-TOY论坛"><p>GET方式访问<a href="http://localhost:3000/noproxy">http://localhost:3000/noproxy</a></p><img src="/2024/07/09/Node-js-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/595580ce54ac8087b903cab0dae5f9b1.png" class="" title="图片[8]-Node.js 创建一个简单的服务实现反向代理-TOY论坛">]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/Node-js/">Node.js</category>
      
      
      <category domain="https://b.122345.xyz/tags/Node-js/">Node.js</category>
      
      <category domain="https://b.122345.xyz/tags/%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/">反向代理</category>
      
      
      <comments>https://b.122345.xyz/2024/07/09/Node-js-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>Spring Security Oauth2.1基本整合配置</title>
      <link>https://b.122345.xyz/2024/07/08/Spring-Security-Oauth2-1%E5%9F%BA%E6%9C%AC%E6%95%B4%E5%90%88%E9%85%8D%E7%BD%AE/</link>
      <guid>https://b.122345.xyz/2024/07/08/Spring-Security-Oauth2-1%E5%9F%BA%E6%9C%AC%E6%95%B4%E5%90%88%E9%85%8D%E7%BD%AE/</guid>
      <pubDate>Mon, 08 Jul 2024 06:59:17 GMT</pubDate>
      
        
        
      <description>&lt;h2 id=&quot;依赖&quot;&gt;&lt;a href=&quot;#依赖&quot; class=&quot;headerlink&quot; title=&quot;依赖&quot;&gt;&lt;/a&gt;依赖&lt;/h2&gt;&lt;p&gt;只需要下面的这一个依赖，springboot 版本为 3.3&lt;/p&gt;
&lt;figure class=&quot;highlight xml&quot;&gt;&lt;tabl</description>
        
      
      
      
      <content:encoded><![CDATA[<h2 id="依赖"><a href="#依赖" class="headerlink" title="依赖"></a>依赖</h2><p>只需要下面的这一个依赖，springboot 版本为 3.3</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></pre></td><td class="code"><pre><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>org.springframework.boot<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>spring-boot-starter-oauth2-authorization-server<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="授权服务AuthorizationServerConfig配置"><a href="#授权服务AuthorizationServerConfig配置" class="headerlink" title="授权服务AuthorizationServerConfig配置"></a>授权服务AuthorizationServerConfig配置</h2><p>spring 官方在快速开始里面给出了下面的默认最小配置<a href="https://blog.122345.xyz/?golink=aHR0cHM6Ly9kb2NzLnNwcmluZy5pby9zcHJpbmctYXV0aG9yaXphdGlvbi1zZXJ2ZXIvcmVmZXJlbmNlL2dldHRpbmctc3RhcnRlZC5odG1s">Spring Authorization Server</a></p><p>AuthorizationServerConfig</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><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AuthorizationServerConfig</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 定义自定义同意页面 URI</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">CUSTOM_CONSENT_PAGE_URI</span> <span class="operator">=</span> <span class="string">&quot;/oauth2/consent&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 配置授权服务器安全过滤器链</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="meta">@Order(1)</span></span><br><span class="line">    <span class="keyword">public</span> SecurityFilterChain <span class="title function_">authorizationServerSecurityFilterChain</span><span class="params">(HttpSecurity http)</span></span><br><span class="line">            <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="comment">// 针对 Spring Authorization Server 最佳实践配置</span></span><br><span class="line">        <span class="comment">// 应用默认的 Spring 授权服务器安全配置</span></span><br><span class="line">        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);</span><br><span class="line"></span><br><span class="line">        http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)</span><br><span class="line">                .authorizationEndpoint(authorizationEndpoint -&gt;</span><br><span class="line">                        authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI))</span><br><span class="line">                .oidc(oidc -&gt; oidc</span><br><span class="line">                        .userInfoEndpoint(userInfo -&gt; userInfo</span><br><span class="line">                                .userInfoResponseHandler(<span class="built_in">this</span>::onAuthenticationSuccess)</span><br><span class="line">                        )</span><br><span class="line">                );    <span class="comment">// 启用 OpenID Connect 1.0</span></span><br><span class="line">        http</span><br><span class="line">                <span class="comment">// Redirect to the login page when not authenticated from the</span></span><br><span class="line">                <span class="comment">// authorization endpoint</span></span><br><span class="line">                <span class="comment">// 未经身份验证时重定向到登录页面</span></span><br><span class="line">                .exceptionHandling((exceptions) -&gt; exceptions</span><br><span class="line">                        .defaultAuthenticationEntryPointFor(</span><br><span class="line">                                <span class="keyword">new</span> <span class="title class_">LoginUrlAuthenticationEntryPoint</span>(<span class="string">&quot;/login&quot;</span>), <span class="comment">// 配置登录地址</span></span><br><span class="line">                                <span class="keyword">new</span> <span class="title class_">MediaTypeRequestMatcher</span>(MediaType.TEXT_HTML)</span><br><span class="line">                        )</span><br><span class="line">                )</span><br><span class="line">                <span class="comment">// Accept access tokens for User Info and/or Client Registration</span></span><br><span class="line">                <span class="comment">// 接受用户信息和/或客户端注册的访问令牌</span></span><br><span class="line">                .oauth2ResourceServer((resourceServer) -&gt; resourceServer</span><br><span class="line">                        .jwt(Customizer.withDefaults()))</span><br><span class="line">                .cors(Customizer.withDefaults());</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> http.build();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 注册客户端存储库</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> RegisteredClientRepository <span class="title function_">registeredClientRepository</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// 注册用户平台客户端</span></span><br><span class="line">        <span class="type">RegisteredClient</span> <span class="variable">wordPress</span> <span class="operator">=</span> RegisteredClient.withId(UUID.randomUUID().toString())</span><br><span class="line">                .clientId(<span class="string">&quot;kil-test&quot;</span>) <span class="comment">// 客户端ID</span></span><br><span class="line">                .clientName(<span class="string">&quot;TOY&quot;</span>) <span class="comment">// 客户端名称</span></span><br><span class="line">                .clientSecret(<span class="string">&quot;&#123;noop&#125;test&quot;</span>) <span class="comment">// 客户端密钥，&#123;noop&#125;表示明文存储</span></span><br><span class="line">                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) <span class="comment">// 客户端认证方法</span></span><br><span class="line">                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) <span class="comment">// 授权类型：授权码模式</span></span><br><span class="line">                .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) <span class="comment">// 刷新令牌授权类型</span></span><br><span class="line">                .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) <span class="comment">// 客户端凭据授权类型</span></span><br><span class="line">                .redirectUri(<span class="string">&quot;https://blog.122345.xyz&quot;</span>) <span class="comment">// 授权码回调地址</span></span><br><span class="line">                .postLogoutRedirectUri(<span class="string">&quot;https://blog.122345.xyz/&quot;</span>) <span class="comment">// 注销后重定向地址</span></span><br><span class="line">                .scope(<span class="string">&quot;profile&quot;</span>) <span class="comment">// 客户端作用域</span></span><br><span class="line">                <span class="comment">// 令牌设置：访问令牌的生存期为1天</span></span><br><span class="line">                .tokenSettings(TokenSettings.builder().accessTokenTimeToLive(Duration.ofDays(<span class="number">1L</span>)).build())</span><br><span class="line">                <span class="comment">// 客户端设置：需要用户授权同意</span></span><br><span class="line">                .clientSettings(ClientSettings.builder().requireAuthorizationConsent(<span class="literal">true</span>).build())</span><br><span class="line">                .build(); <span class="comment">// 构建注册的客户端</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">InMemoryRegisteredClientRepository</span>(wordPress);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 定义一个名为jwtTokenCustomizer的Bean，用于定制JWT令牌</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> OAuth2TokenCustomizer&lt;JwtEncodingContext&gt; <span class="title function_">jwtTokenCustomizer</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// 返回一个Lambda表达式，定制JWT令牌的内容</span></span><br><span class="line">        <span class="keyword">return</span> (context) -&gt; &#123;</span><br><span class="line">            <span class="comment">// 检查令牌类型是否为访问令牌</span></span><br><span class="line">            <span class="keyword">if</span> (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) &#123;</span><br><span class="line">                <span class="comment">// 获取JWT令牌的声明部分</span></span><br><span class="line">                context.getClaims().claims((claims) -&gt; &#123;</span><br><span class="line">                    <span class="comment">// 获取用户权限列表并转换为Set集合</span></span><br><span class="line">                    Set&lt;String&gt; roles = AuthorityUtils.authorityListToSet(context.getPrincipal().getAuthorities())</span><br><span class="line">                            .stream()</span><br><span class="line">                            <span class="comment">// 将权限中的&quot;ROLE_&quot;前缀去除</span></span><br><span class="line">                            .map(c -&gt; c.replaceFirst(<span class="string">&quot;^ROLE_&quot;</span>, <span class="string">&quot;&quot;</span>))</span><br><span class="line">                            <span class="comment">// 转换为不可变的Set集合</span></span><br><span class="line">                            .collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet));</span><br><span class="line"></span><br><span class="line">                    <span class="comment">// 将角色信息放入JWT令牌的声明中的&quot;roles&quot;字段</span></span><br><span class="line">                    claims.put(<span class="string">&quot;roles&quot;</span>, roles);</span><br><span class="line">                &#125;);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 定义一个名为jwkSource的Bean，用于提供JSON Web Key (JWK)</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> JWKSource&lt;SecurityContext&gt; <span class="title function_">jwkSource</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// 生成RSA密钥对</span></span><br><span class="line">        <span class="type">KeyPair</span> <span class="variable">keyPair</span> <span class="operator">=</span> generateRsaKey();</span><br><span class="line">        <span class="comment">// 获取公钥</span></span><br><span class="line">        <span class="type">RSAPublicKey</span> <span class="variable">publicKey</span> <span class="operator">=</span> (RSAPublicKey) keyPair.getPublic();</span><br><span class="line">        <span class="comment">// 获取私钥</span></span><br><span class="line">        <span class="type">RSAPrivateKey</span> <span class="variable">privateKey</span> <span class="operator">=</span> (RSAPrivateKey) keyPair.getPrivate();</span><br><span class="line">        <span class="comment">// 创建RSAKey对象</span></span><br><span class="line">        <span class="type">RSAKey</span> <span class="variable">rsaKey</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">RSAKey</span>.Builder(publicKey)</span><br><span class="line">                <span class="comment">// 设置私钥</span></span><br><span class="line">                .privateKey(privateKey)</span><br><span class="line">                <span class="comment">// 设置Key ID</span></span><br><span class="line">                .keyID(UUID.randomUUID().toString())</span><br><span class="line">                <span class="comment">// 构建RSAKey对象</span></span><br><span class="line">                .build();</span><br><span class="line">        <span class="comment">// 创建JWKSet对象，包含上面创建的RSAKey</span></span><br><span class="line">        <span class="type">JWKSet</span> <span class="variable">jwkSet</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JWKSet</span>(rsaKey);</span><br><span class="line">        <span class="comment">// 返回一个不可变的JWKSet</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ImmutableJWKSet</span>&lt;&gt;(jwkSet);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 定义一个静态方法用于生成RSA密钥对</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> KeyPair <span class="title function_">generateRsaKey</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// 声明KeyPair对象</span></span><br><span class="line">        KeyPair keyPair;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">// 获取RSA算法的密钥对生成器实例</span></span><br><span class="line">            <span class="type">KeyPairGenerator</span> <span class="variable">keyPairGenerator</span> <span class="operator">=</span> KeyPairGenerator.getInstance(<span class="string">&quot;RSA&quot;</span>);</span><br><span class="line">            <span class="comment">// 初始化密钥对生成器，指定密钥长度为2048位</span></span><br><span class="line">            keyPairGenerator.initialize(<span class="number">2048</span>);</span><br><span class="line">            <span class="comment">// 生成RSA密钥对</span></span><br><span class="line">            keyPair = keyPairGenerator.generateKeyPair();</span><br><span class="line">            <span class="comment">// 捕获可能的异常</span></span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception ex) &#123;</span><br><span class="line">            <span class="comment">// 抛出异常</span></span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">IllegalStateException</span>(ex);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 返回生成的RSA密钥对</span></span><br><span class="line">        <span class="keyword">return</span> keyPair;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 定义一个名为jwtDecoder的Bean，接受一个JWKSource&lt;SecurityContext&gt;作为参数</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> JwtDecoder <span class="title function_">jwtDecoder</span><span class="params">(JWKSource&lt;SecurityContext&gt; jwkSource)</span> &#123;</span><br><span class="line">        <span class="comment">// 调用OAuth2AuthorizationServerConfiguration类的jwtDecoder方法，并传入jwkSource作为参数</span></span><br><span class="line">        <span class="keyword">return</span> OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 定义一个名为authorizationServerSettings的Bean</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> AuthorizationServerSettings <span class="title function_">authorizationServerSettings</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// 使用AuthorizationServerSettings的构建器模式创建一个实例并返回</span></span><br><span class="line">        <span class="keyword">return</span> AuthorizationServerSettings.builder().build();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 授权成功返回信息</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onAuthenticationSuccess</span><span class="params">(HttpServletRequest request, HttpServletResponse response, Authentication authentication)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="comment">// 当认证成功时执行的方法，接受HttpServletRequest、HttpServletResponse和Authentication作为参数</span></span><br><span class="line">        <span class="comment">// 将Authentication转换为OidcUserInfoAuthenticationToken类型，以便获取用户信息</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 设置响应的Content-Type为application/json，并指定字符集为UTF-8</span></span><br><span class="line">        response.setContentType(<span class="string">&quot;application/json;charset=UTF-8&quot;</span>);</span><br><span class="line">        <span class="comment">// 设置响应的状态码为200（HttpStatus.OK.value()返回的是200）</span></span><br><span class="line">        response.setStatus(HttpStatus.OK.value());</span><br><span class="line">        <span class="comment">// 将request中的用户主体信息转换为JSON字符串并写入响应的输出流中</span></span><br><span class="line">        response.getWriter().write(JSON.toJSONString(request.getUserPrincipal()));</span><br><span class="line">        <span class="comment">// 刷新响应的输出流</span></span><br><span class="line">        response.getWriter().flush();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><table><thead><tr><th align="center">权限范围</th><th align="center">声明</th></tr></thead><tbody><tr><td align="center"><strong>openid</strong></td><td align="center"><strong>sub</strong></td></tr><tr><td align="center">profile</td><td align="center">Name、family_name、given_name、middle_name、nickname、preferred_username、profile、 picture、website、gender、birthdate、zoneinfo、locale、updated_at</td></tr><tr><td align="center">email</td><td align="center">email、email_verified</td></tr><tr><td align="center">address</td><td align="center">address,是一个 JSON 对象、包含 formatted、street_address、locality、region、postal_code、country</td></tr><tr><td align="center">phone</td><td align="center">phone_number、phone_number_verified</td></tr></tbody></table><p>DefaultSecurityConfig</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><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@EnableWebSecurity</span></span><br><span class="line"><span class="meta">@Configuration(proxyBeanMethods = false)</span> <span class="comment">//不使用代理来优化 @Configuration 类中的 @Bean 方法</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">DefaultSecurityConfig</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="meta">@Order(2)</span></span><br><span class="line">    <span class="keyword">public</span> SecurityFilterChain <span class="title function_">defaultSecurityFilterChain</span><span class="params">(HttpSecurity http)</span></span><br><span class="line">            <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="comment">// 定义一个安全过滤器链，指定顺序为2</span></span><br><span class="line">        http</span><br><span class="line">                .authorizeHttpRequests((authorize) -&gt; authorize</span><br><span class="line">                        <span class="comment">// 配置不需要验证的地址</span></span><br><span class="line">                        .requestMatchers(<span class="keyword">new</span> <span class="title class_">AntPathRequestMatcher</span>(<span class="string">&quot;/actuator/**&quot;</span>),</span><br><span class="line">                                <span class="keyword">new</span> <span class="title class_">AntPathRequestMatcher</span>(<span class="string">&quot;/oauth2/**&quot;</span>),</span><br><span class="line">                                <span class="keyword">new</span> <span class="title class_">AntPathRequestMatcher</span>(<span class="string">&quot;/login&quot;</span>),</span><br><span class="line">                                <span class="keyword">new</span> <span class="title class_">AntPathRequestMatcher</span>(<span class="string">&quot;/**/*.json&quot;</span>),</span><br><span class="line">                                <span class="keyword">new</span> <span class="title class_">AntPathRequestMatcher</span>(<span class="string">&quot;/**/*.html&quot;</span>),</span><br><span class="line">                                <span class="comment">// 对指定的地址不进行认证，允许所有访问</span></span><br><span class="line">                                <span class="keyword">new</span> <span class="title class_">AntPathRequestMatcher</span>(<span class="string">&quot;/**/*.png&quot;</span>)).permitAll()</span><br><span class="line">                        <span class="comment">// 其他地址需要认证</span></span><br><span class="line">                        .anyRequest().authenticated()</span><br><span class="line">                )</span><br><span class="line">                <span class="comment">// 启用默认的跨域配置</span></span><br><span class="line">                .cors(Customizer.withDefaults())</span><br><span class="line">                <span class="comment">// 禁用CSRF保护</span></span><br><span class="line">                .csrf(AbstractHttpConfigurer::disable)</span><br><span class="line"><span class="comment">//                .httpBasic(Customizer.withDefaults())</span></span><br><span class="line"><span class="comment">//           Form login handles the redirect to the login page from the</span></span><br><span class="line"><span class="comment">//           authorization server filter chain</span></span><br><span class="line">                <span class="comment">// 启用HTTP基本认证，使用默认配置</span></span><br><span class="line">                <span class="comment">// 登录的url</span></span><br><span class="line">                .formLogin(form -&gt; form</span><br><span class="line">                        <span class="comment">// 登录的url</span></span><br><span class="line">                        .loginPage(<span class="string">&quot;/login&quot;</span>)</span><br><span class="line">                        <span class="comment">// 指定用于处理登录的URL</span></span><br><span class="line">                        .loginProcessingUrl(<span class="string">&quot;/login&quot;</span>))</span><br><span class="line">        ;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 构建并返回SecurityFilterChain</span></span><br><span class="line">        <span class="keyword">return</span> http.build();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 跨域请求配置</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> CorsConfigurationSource <span class="title function_">corsConfigurationSource</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// 定义跨域配置源</span></span><br><span class="line">        <span class="type">UrlBasedCorsConfigurationSource</span> <span class="variable">source</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">UrlBasedCorsConfigurationSource</span>();</span><br><span class="line">        <span class="type">CorsConfiguration</span> <span class="variable">config</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">CorsConfiguration</span>();</span><br><span class="line">        <span class="comment">// 允许所有头部</span></span><br><span class="line">        config.addAllowedHeader(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">        <span class="comment">// 允许所有方法</span></span><br><span class="line">        config.addAllowedMethod(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">        <span class="comment">// 允许所有来源</span></span><br><span class="line">        config.addAllowedOriginPattern(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">        <span class="comment">// 允许发送身份验证信息</span></span><br><span class="line">        config.setAllowCredentials(<span class="literal">true</span>);</span><br><span class="line">        <span class="comment">// 预检请求的有效期，单位为秒</span></span><br><span class="line">        config.setMaxAge(<span class="number">3600L</span>);</span><br><span class="line">        <span class="comment">// 对所有路径应用上述配置</span></span><br><span class="line">        source.registerCorsConfiguration(<span class="string">&quot;/**&quot;</span>, config);</span><br><span class="line">        <span class="comment">// 返回配置源</span></span><br><span class="line">        <span class="keyword">return</span> source;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="持久化客户端"><a href="#持久化客户端" class="headerlink" title="持久化客户端"></a>持久化客户端</h2><p>AuthorizationServerConfig类添加</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><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line">    <span class="comment">// 注册客户端存储库</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> RegisteredClientRepository <span class="title function_">registeredClientRepository</span><span class="params">(JdbcTemplate jdbcTemplate)</span> &#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">        // 注册用户平台客户端</span></span><br><span class="line"><span class="comment">        RegisteredClient wordPress = RegisteredClient.withId(UUID.randomUUID().toString())</span></span><br><span class="line"><span class="comment">                .clientId(&quot;kil-blog&quot;) // 客户端ID</span></span><br><span class="line"><span class="comment">                .clientName(&quot;TOY论坛&quot;) // 客户端名称</span></span><br><span class="line"><span class="comment">                .clientSecret(&quot;&#123;noop&#125;kilCat&quot;) // 客户端密钥，&#123;noop&#125;表示明文存储</span></span><br><span class="line"><span class="comment">                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) // 客户端认证方法</span></span><br><span class="line"><span class="comment">                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) // 授权类型：授权码模式</span></span><br><span class="line"><span class="comment">                .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) // 刷新令牌授权类型</span></span><br><span class="line"><span class="comment">                .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) // 客户端凭据授权类型</span></span><br><span class="line"><span class="comment">                .redirectUri(&quot;https://blog.122345.xyz&quot;) // 授权码回调地址</span></span><br><span class="line"><span class="comment">                .postLogoutRedirectUri(&quot;https://blog.122345.xyz&quot;) // 注销后重定向地址</span></span><br><span class="line"><span class="comment">                .scope(OidcScopes.OPENID)</span></span><br><span class="line"><span class="comment">                .scope(OidcScopes.PROFILE)</span></span><br><span class="line"><span class="comment">                .scope(&quot;message.read&quot;)</span></span><br><span class="line"><span class="comment">                .scope(&quot;message.write&quot;)</span></span><br><span class="line"><span class="comment">                .scope(&quot;all&quot;) // 客户端作用域</span></span><br><span class="line"><span class="comment">                // 令牌设置：访问令牌的生存期为1天</span></span><br><span class="line"><span class="comment">                .tokenSettings(TokenSettings.builder().accessTokenTimeToLive(Duration.ofDays(1L)).build())</span></span><br><span class="line"><span class="comment">                // 客户端设置：需要用户授权同意</span></span><br><span class="line"><span class="comment">                .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())</span></span><br><span class="line"><span class="comment">                .build(); // 构建注册的客户端</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// Save registered client&#x27;s in db as if in-memory</span></span><br><span class="line">        <span class="comment">// registeredClientRepository.save(wordPress);</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">JdbcRegisteredClientRepository</span>(jdbcTemplate);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> JdbcOAuth2AuthorizationService <span class="title function_">auth2AuthorizationService</span><span class="params">(JdbcTemplate jdbcTemplate,</span></span><br><span class="line"><span class="params">                                                                    RegisteredClientRepository registeredClientRepository)</span> &#123;</span><br><span class="line">        <span class="comment">// 这个 Bean 用于管理 OAuth2 授权。</span></span><br><span class="line">        <span class="comment">// 它需要两个参数：jdbcTemplate 和 registeredClientRepository。</span></span><br><span class="line">        <span class="comment">// jdbcTemplate 是 Spring JDBC 模板，用于执行 SQL 查询和更新操作。</span></span><br><span class="line">        <span class="comment">// registeredClientRepository 是一个接口，用于管理 OAuth2 客户端的注册信息。</span></span><br><span class="line">        <span class="comment">// 这个 Bean 将 OAuth2 授权信息存储到数据库中，并提供查询和删除授权信息的方法。</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">JdbcOAuth2AuthorizationService</span>(jdbcTemplate, registeredClientRepository);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> JdbcOAuth2AuthorizationConsentService <span class="title function_">auth2AuthorizationConsentService</span><span class="params">(JdbcTemplate jdbcTemplate,</span></span><br><span class="line"><span class="params">                                                                                  RegisteredClientRepository registeredClientRepository)</span> &#123;</span><br><span class="line">        <span class="comment">// 这个 Bean 用于管理 OAuth2 授权同意。</span></span><br><span class="line">        <span class="comment">// 它也需要 jdbcTemplate 和 registeredClientRepository 作为参数。</span></span><br><span class="line">        <span class="comment">// 这个 Bean 将 OAuth2 授权同意信息存储到数据库中，并提供查询和删除授权同意信息的方法。</span></span><br><span class="line">        <span class="comment">// 它将被 ConsentController 使用。</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">JdbcOAuth2AuthorizationConsentService</span>(jdbcTemplate, registeredClientRepository);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><p>sql参考官方项目 <a href="https://blog.122345.xyz/?golink=aHR0cHM6Ly9naXRodWIuY29tL3NwcmluZy1wcm9qZWN0cy9zcHJpbmctYXV0aG9yaXphdGlvbi1zZXJ2ZXIvdHJlZS9tYWluL29hdXRoMi1hdXRob3JpemF0aW9uLXNlcnZlci9zcmMvbWFpbi9yZXNvdXJjZXMvb3JnL3NwcmluZ2ZyYW1ld29yay9zZWN1cml0eS9vYXV0aDIvc2VydmVyL2F1dGhvcml6YXRpb24=">spring-authorization-server</a></p><p>官方dome<a href="https://blog.122345.xyz/?golink=aHR0cHM6Ly9naXRodWIuY29tL3NwcmluZy1wcm9qZWN0cy9zcHJpbmctYXV0aG9yaXphdGlvbi1zZXJ2ZXIvdHJlZS9tYWluL3NhbXBsZXMvZGVtby1hdXRob3JpemF0aW9uc2VydmVy"> demo-authorizationserver</a></p><h2 id="修改pom"><a href="#修改pom" class="headerlink" title="修改pom"></a>修改pom</h2><p>需要额外引入spring security cas包原因是启动时(logging等级：org.springframework.security: trace)会报错：java.lang.ClassNotFoundException:org.springframework.security.cas.jackson2.CasJackson2Module错误。</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></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 添加spring security cas支持</span></span><br><span class="line"><span class="comment">         这里需添加spring-security-cas依赖，</span></span><br><span class="line"><span class="comment">         否则启动时报java.lang.ClassNotFoundException: org.springframework.security.cas.jackson2.CasJackson2Module错误。</span></span><br><span class="line"><span class="comment">         --&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>org.springframework.security<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>spring-security-cas<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure>]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/java/">java</category>
      
      <category domain="https://b.122345.xyz/categories/java/spring/">spring</category>
      
      
      <category domain="https://b.122345.xyz/tags/java/">java</category>
      
      <category domain="https://b.122345.xyz/tags/spring/">spring</category>
      
      <category domain="https://b.122345.xyz/tags/spring-boot/">spring-boot</category>
      
      
      <comments>https://b.122345.xyz/2024/07/08/Spring-Security-Oauth2-1%E5%9F%BA%E6%9C%AC%E6%95%B4%E5%90%88%E9%85%8D%E7%BD%AE/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>RequestParam，PathParam，PathVariable等注解区别</title>
      <link>https://b.122345.xyz/2024/03/28/RequestParam%EF%BC%8CPathParam%EF%BC%8CPathVariable%E7%AD%89%E6%B3%A8%E8%A7%A3%E5%8C%BA%E5%88%AB/</link>
      <guid>https://b.122345.xyz/2024/03/28/RequestParam%EF%BC%8CPathParam%EF%BC%8CPathVariable%E7%AD%89%E6%B3%A8%E8%A7%A3%E5%8C%BA%E5%88%AB/</guid>
      <pubDate>Thu, 28 Mar 2024 07:05:32 GMT</pubDate>
      
        
        
      <description>&lt;p&gt;&lt;code&gt;@RequestParam&lt;/code&gt; 和 &lt;code&gt;@PathVariable&lt;/code&gt; 注解是用于从request中接收请求的，两个都可以接收参数，关键点不同的是&lt;code&gt;@RequestParam&lt;/code&gt; 是从request里面拿取值，而 </description>
        
      
      
      
      <content:encoded><![CDATA[<p><code>@RequestParam</code> 和 <code>@PathVariable</code> 注解是用于从request中接收请求的，两个都可以接收参数，关键点不同的是<code>@RequestParam</code> 是从request里面拿取值，而 <code>@PathVariable</code> 是从一个URI模板里面来填充</p><h2 id="RequestParam"><a href="#RequestParam" class="headerlink" title="@RequestParam"></a>@RequestParam</h2><p>看下面一段代码：</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">http://localhost:8080/springmvc/hello/101?param1=10&amp;param2=20</span><br></pre></td></tr></table></figure><p>根据上面的这个URL，你可以用这样的方式来进行获取</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> String <span class="title function_">getDetails</span><span class="params">(</span></span><br><span class="line"><span class="params">    <span class="meta">@RequestParam(value=&quot;param1&quot;, required=true)</span> String param1,</span></span><br><span class="line"><span class="params">        <span class="meta">@RequestParam(value=&quot;param2&quot;, required=false)</span> String param2)</span>&#123;</span><br><span class="line">...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><code>@RequestParam</code> 支持下面四种参数</p><ul><li>defaultValue 如果本次请求没有携带这个参数，或者参数为空，那么就会启用默认值</li><li>name 绑定本次参数的名称，要跟URL上面的一样</li><li>required 这个参数是不是必须的</li><li>value 跟name一样的作用，是name属性的一个别名</li></ul><h2 id="PathVariable"><a href="#PathVariable" class="headerlink" title="@PathVariable"></a>@PathVariable</h2><p>这个注解能够识别URL里面的一个模板，我们看下面的一个URL</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">http://localhost:8080/springmvc/hello/101?param1=10&amp;param2=20</span><br></pre></td></tr></table></figure><p>上面的一个url你可以这样写：</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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping(&quot;/hello/&#123;id&#125;&quot;)</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getDetails</span><span class="params">(<span class="meta">@PathVariable(value=&quot;id&quot;)</span> String id,</span></span><br><span class="line"><span class="params"></span></span><br><span class="line"><span class="params">    <span class="meta">@RequestParam(value=&quot;param1&quot;, required=true)</span> String param1,</span></span><br><span class="line"><span class="params"></span></span><br><span class="line"><span class="params">    <span class="meta">@RequestParam(value=&quot;param2&quot;, required=false)</span> String param2)</span>&#123;</span><br><span class="line"></span><br><span class="line">.......</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>区别很明显了</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><ul><li>@PathParam</li></ul><p>这个注解是和spring的<code>pathVariable</code>是一样的，也是基于模板的，但是这个是jboss包下面的一个实现，上面的是spring的一个实现，都要导包</p><ul><li>@QueryParam</li></ul><p><code>@QueryParam</code> 是 JAX-RS 本来就提供的，和Spring的RequestParam作用一致</p><ul><li>@ResponseBody</li></ul><p>responseBody表示服务器返回的时候以一种什么样的方式进行返回， 将内容或对象作为 HTTP 响应正文返回，值有很多，一般设定为json</p><ul><li>@RequestBody</li></ul><p>一般是post请求的时候才会使用这个请求，把参数丢在requestbody里面</p>]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/java/">java</category>
      
      <category domain="https://b.122345.xyz/categories/java/spring/">spring</category>
      
      
      <category domain="https://b.122345.xyz/tags/spring/">spring</category>
      
      <category domain="https://b.122345.xyz/tags/spring-boot/">spring-boot</category>
      
      <category domain="https://b.122345.xyz/tags/PathVariable/">PathVariable</category>
      
      <category domain="https://b.122345.xyz/tags/RequestParam/">RequestParam</category>
      
      <category domain="https://b.122345.xyz/tags/PathParam/">PathParam</category>
      
      
      <comments>https://b.122345.xyz/2024/03/28/RequestParam%EF%BC%8CPathParam%EF%BC%8CPathVariable%E7%AD%89%E6%B3%A8%E8%A7%A3%E5%8C%BA%E5%88%AB/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>Spring Boot项目全局异常处理方式</title>
      <link>https://b.122345.xyz/2024/03/28/Spring-Boot%E9%A1%B9%E7%9B%AE%E5%85%A8%E5%B1%80%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%E6%96%B9%E5%BC%8F/</link>
      <guid>https://b.122345.xyz/2024/03/28/Spring-Boot%E9%A1%B9%E7%9B%AE%E5%85%A8%E5%B1%80%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%E6%96%B9%E5%BC%8F/</guid>
      <pubDate>Thu, 28 Mar 2024 06:34:09 GMT</pubDate>
      
        
        
      <description>&lt;p&gt;SpringBoot中，&lt;font color=orange&gt;@ControllerAdvice&lt;/font&gt; 即可开启全局异常处理，使用该注解表示开启了全局异常的捕获，我们只需在自定义一个方法使用&lt;font color=orange&gt;@ExceptionHandler&lt;/</description>
        
      
      
      
      <content:encoded><![CDATA[<p>SpringBoot中，<font color=orange>@ControllerAdvice</font> 即可开启全局异常处理，使用该注解表示开启了全局异常的捕获，我们只需在自定义一个方法使用<font color=orange>@ExceptionHandler</font>注解然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。</p><h2 id="添加-ControllerAdvice自定义全局异常处理器"><a href="#添加-ControllerAdvice自定义全局异常处理器" class="headerlink" title="添加@ControllerAdvice自定义全局异常处理器"></a>添加@ControllerAdvice自定义全局异常处理器</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestControllerAdvice</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">GlobalExceptionHandler</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//默认全局异常处理</span></span><br><span class="line">    <span class="meta">@ExceptionHandler(Exception.class)</span></span><br><span class="line">    <span class="meta">@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)</span></span><br><span class="line">    <span class="keyword">public</span> ResultData&lt;String&gt; <span class="title function_">exception</span><span class="params">(Exception e)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> ResultData.fail(ReturnCode.RC500.getCode(), e.getMessage());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 自定义错误异常处理</span></span><br><span class="line">    <span class="meta">@ExceptionHandler(ServiceException.class)</span></span><br><span class="line">    <span class="keyword">public</span> ResultData&lt;String&gt; <span class="title function_">serviceException</span><span class="params">(ServiceException e)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> ResultData.fail(e.getCode(), e.getMessage());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>全局异常处理器注解说明：</li></ul><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@ExceptionHandler(value = MyException.class)</span> -- 注解类型</span><br><span class="line"><span class="meta">@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)</span> -- 错误码</span><br><span class="line"><span class="meta">@ResponseBody</span> --  返回json</span><br><span class="line"><span class="meta">@ControllerAdvice</span> -- 顾名思义，这是一个增强的 Controller。使用这个 Controller ，可以实现三个方面的功能：</span><br><span class="line"><span class="number">1.</span>全局异常处理</span><br><span class="line"><span class="number">2.</span>全局数据绑定</span><br><span class="line"><span class="number">3.</span>全局数据预处理</span><br></pre></td></tr></table></figure><h2 id="定义枚举类"><a href="#定义枚举类" class="headerlink" title="定义枚举类"></a>定义枚举类</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Getter</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> <span class="title class_">ReturnCode</span> &#123;</span><br><span class="line">    RC100(<span class="number">100</span>, <span class="string">&quot;操作成功&quot;</span>),</span><br><span class="line">    RC999(<span class="number">999</span>, <span class="string">&quot;操作失败&quot;</span>),</span><br><span class="line">    RC200(<span class="number">200</span>, <span class="string">&quot;服务开启限流保护，请稍后再试！&quot;</span>),</span><br><span class="line">    RC201(<span class="number">201</span>, <span class="string">&quot;服务开启降级保护，请稍后再试！&quot;</span>),</span><br><span class="line">    RC202(<span class="number">202</span>, <span class="string">&quot;热点参数限流，请稍后再试！&quot;</span>),</span><br><span class="line">    RC203(<span class="number">203</span>, <span class="string">&quot;系统规则不满足要求，请稍后再试！&quot;</span>),</span><br><span class="line">    RC204(<span class="number">204</span>, <span class="string">&quot;系统规则不通过，请稍后再试！&quot;</span>),</span><br><span class="line">    RC403(<span class="number">403</span>, <span class="string">&quot;无访问权限，请联系管理员授予权限&quot;</span>),</span><br><span class="line">    RC401(<span class="number">401</span>, <span class="string">&quot;匿名用户访问无权限资源异常&quot;</span>),</span><br><span class="line">    RC500(<span class="number">500</span>, <span class="string">&quot;系统错误，请稍后重试&quot;</span>),</span><br><span class="line"></span><br><span class="line">    INVALID_TOKEN(<span class="number">2001</span>, <span class="string">&quot;访问令牌不合法&quot;</span>),</span><br><span class="line">    ACCESS_DENIED(<span class="number">2003</span>, <span class="string">&quot;没有权限访问该资源&quot;</span>),</span><br><span class="line">    CLIENT_AUTHENTICATION_FAILED(<span class="number">1001</span>, <span class="string">&quot;客户端认证失败&quot;</span>),</span><br><span class="line">    USERNAME_OR_PASSWORD_ERROR(<span class="number">1002</span>, <span class="string">&quot;用户名或密码错误&quot;</span>),</span><br><span class="line">    UNSUPPORTED_GRANT_TYPE(<span class="number">1003</span>, <span class="string">&quot;不支持的认证模式&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">int</span> code;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> String message;</span><br><span class="line">    ReturnCode(<span class="type">int</span> code, String message)&#123;</span><br><span class="line">        <span class="built_in">this</span>.code = code;</span><br><span class="line">        <span class="built_in">this</span>.message = message;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="自定义异常类"><a href="#自定义异常类" class="headerlink" title="自定义异常类"></a>自定义异常类</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Getter</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ServiceException</span> <span class="keyword">extends</span> <span class="title class_">RuntimeException</span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 错误码</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">int</span> code;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 通过自定义枚举类设置错误信息</span></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">ServiceException</span><span class="params">(ReturnCode returnCode)</span>&#123;</span><br><span class="line">        <span class="built_in">super</span>(returnCode.getMessage());</span><br><span class="line">        <span class="built_in">this</span>.code = returnCode.getCode();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">ServiceException</span><span class="params">(Integer code, String message)</span>&#123;</span><br><span class="line">        <span class="built_in">super</span>(message);</span><br><span class="line">        <span class="built_in">this</span>.code = code;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="自定义数据返回类"><a href="#自定义数据返回类" class="headerlink" title="自定义数据返回类"></a>自定义数据返回类</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ResultData</span>&lt;T&gt; &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> status;</span><br><span class="line">    <span class="keyword">private</span> String message;</span><br><span class="line">    <span class="keyword">private</span> T data;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">long</span> timestamp;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">ResultData</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="built_in">this</span>.timestamp = System.currentTimeMillis();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; ResultData&lt;T&gt; <span class="title function_">success</span><span class="params">(T data)</span>&#123;</span><br><span class="line">        ResultData&lt;T&gt; resultData = <span class="keyword">new</span> <span class="title class_">ResultData</span>&lt;&gt;();</span><br><span class="line">        resultData.setStatus(ReturnCode.RC100.getCode());</span><br><span class="line">        resultData.setMessage(ReturnCode.RC100.getMessage());</span><br><span class="line">        resultData.setData(data);</span><br><span class="line">        <span class="keyword">return</span> resultData;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; ResultData&lt;T&gt; <span class="title function_">fail</span><span class="params">(<span class="type">int</span> code, String message)</span>&#123;</span><br><span class="line">        ResultData&lt;T&gt; resultData = <span class="keyword">new</span> <span class="title class_">ResultData</span>&lt;&gt;();</span><br><span class="line">        resultData.setStatus(code);</span><br><span class="line">        resultData.setMessage(message);</span><br><span class="line">        <span class="keyword">return</span> resultData;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@GetMapping(&quot;/info/&#123;attrId&#125;&quot;)</span></span><br><span class="line"><span class="keyword">public</span> ProductAttr <span class="title function_">getAttrIdById</span><span class="params">(<span class="meta">@PathVariable(&quot;attrId&quot;)</span> Long attrId)</span>&#123;</span><br><span class="line">    <span class="comment">// throw new ServiceException(ReturnCode.INVALID_TOKEN); //抛出自定义异常</span></span><br><span class="line">    <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">10</span> / <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">return</span> productAttrService.getById(attrId);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>返回数据</p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;status&quot;</span><span class="punctuation">:</span> <span class="number">500</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;message&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/ by zero&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;data&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">null</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;timestamp&quot;</span><span class="punctuation">:</span> <span class="number">1711618149074</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/java/">java</category>
      
      <category domain="https://b.122345.xyz/categories/java/spring/">spring</category>
      
      
      <category domain="https://b.122345.xyz/tags/java/">java</category>
      
      <category domain="https://b.122345.xyz/tags/spring/">spring</category>
      
      <category domain="https://b.122345.xyz/tags/spring-boot/">spring-boot</category>
      
      
      <comments>https://b.122345.xyz/2024/03/28/Spring-Boot%E9%A1%B9%E7%9B%AE%E5%85%A8%E5%B1%80%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%E6%96%B9%E5%BC%8F/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>springboot项目使用advice做统一返回处理</title>
      <link>https://b.122345.xyz/2024/03/28/springboot%E9%A1%B9%E7%9B%AE%E4%BD%BF%E7%94%A8advice%E5%81%9A%E7%BB%9F%E4%B8%80%E8%BF%94%E5%9B%9E%E5%A4%84%E7%90%86/</link>
      <guid>https://b.122345.xyz/2024/03/28/springboot%E9%A1%B9%E7%9B%AE%E4%BD%BF%E7%94%A8advice%E5%81%9A%E7%BB%9F%E4%B8%80%E8%BF%94%E5%9B%9E%E5%A4%84%E7%90%86/</guid>
      <pubDate>Thu, 28 Mar 2024 04:48:30 GMT</pubDate>
      
        
        
      <description>&lt;h2 id=&quot;ResponseBodyAdvice接口&quot;&gt;&lt;a href=&quot;#ResponseBodyAdvice接口&quot; class=&quot;headerlink&quot; title=&quot;ResponseBodyAdvice接口&quot;&gt;&lt;/a&gt;ResponseBodyAdvice接口&lt;/h2&gt;&lt;</description>
        
      
      
      
      <content:encoded><![CDATA[<h2 id="ResponseBodyAdvice接口"><a href="#ResponseBodyAdvice接口" class="headerlink" title="ResponseBodyAdvice接口"></a>ResponseBodyAdvice接口</h2><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">ResponseBodyAdvice</span>&lt;T&gt; &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 是否支持advice功能</span></span><br><span class="line">    <span class="comment">// true 支持，false 不支持</span></span><br><span class="line">    <span class="type">boolean</span> <span class="title function_">supports</span><span class="params">(MethodParameter returnType, Class&lt;? extends HttpMessageConverter&lt;?&gt;&gt; converterType)</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 对返回数据进行处理</span></span><br><span class="line">    <span class="meta">@Nullable</span></span><br><span class="line">    T <span class="title function_">beforeBodyWrite</span><span class="params">(<span class="meta">@Nullable</span> T body, MethodParameter returnType, MediaType selectedContentType, Class&lt;? extends HttpMessageConverter&lt;?&gt;&gt; selectedConverterType, ServerHttpRequest request, ServerHttpResponse response)</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="创建一个处理类实现ResponseBodyAdvice接口"><a href="#创建一个处理类实现ResponseBodyAdvice接口" class="headerlink" title="创建一个处理类实现ResponseBodyAdvice接口"></a>创建一个处理类实现ResponseBodyAdvice接口</h2><p>记得添加@RestControllerAdvice注解</p><p>@RestControllerAdvice注解是@RestController注解的增强，可以实现三个方面的功能：</p><ul><li>全局异常处理</li><li>全局数据绑定</li><li>全局数据预处理</li></ul><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestControllerAdvice</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ResponseAdvice</span> <span class="keyword">implements</span> <span class="title class_">ResponseBodyAdvice</span>&lt;Object&gt; &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Resource</span></span><br><span class="line">    <span class="keyword">private</span> ObjectMapper objectMapper;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">supports</span><span class="params">(<span class="meta">@NonNull</span> MethodParameter returnType, <span class="meta">@NonNull</span> Class&lt;? extends HttpMessageConverter&lt;?&gt;&gt; converterType)</span> &#123;</span><br><span class="line">        <span class="comment">// 判断是否要执行beforeBodyWrite方法，true为执行，false不执行</span></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 对response处理的执行方法</span></span><br><span class="line">    <span class="meta">@SneakyThrows</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Object <span class="title function_">beforeBodyWrite</span><span class="params">(Object body, <span class="meta">@NonNull</span> MethodParameter returnType, <span class="meta">@NonNull</span> MediaType selectedContentType, <span class="meta">@NonNull</span> Class&lt;? extends HttpMessageConverter&lt;?&gt;&gt; selectedConverterType, <span class="meta">@NonNull</span> ServerHttpRequest request, <span class="meta">@NonNull</span> ServerHttpResponse response)</span> &#123;</span><br><span class="line">        <span class="comment">// String类型不能直接包装，所以要进行些特别的处理</span></span><br><span class="line">        <span class="keyword">if</span> (body <span class="keyword">instanceof</span> String)&#123;</span><br><span class="line">            <span class="comment">// 将数据包装在BaseResult里后，再转换为json字符串响应给前端</span></span><br><span class="line">            <span class="keyword">return</span> objectMapper.writeValueAsString(ResultData.success(body));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 已经封装则直接返回</span></span><br><span class="line">        <span class="keyword">if</span> (body <span class="keyword">instanceof</span> ResultData)&#123;</span><br><span class="line">            <span class="keyword">return</span> body;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 将原本的数据包装ResultData在里</span></span><br><span class="line">        <span class="keyword">return</span> ResultData.success(body);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>ResultData类</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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ResultData</span>&lt;T&gt; &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> status;</span><br><span class="line">    <span class="keyword">private</span> String message;</span><br><span class="line">    <span class="keyword">private</span> T data;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">long</span> timestamp;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">ResultData</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="built_in">this</span>.timestamp = System.currentTimeMillis();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; ResultData&lt;T&gt; <span class="title function_">success</span><span class="params">(T data)</span>&#123;</span><br><span class="line">        ResultData&lt;T&gt; resultData = <span class="keyword">new</span> <span class="title class_">ResultData</span>&lt;&gt;();</span><br><span class="line">        resultData.setStatus(ReturnCode.RC100.getCode());</span><br><span class="line">        resultData.setMessage(ReturnCode.RC100.getMessage());</span><br><span class="line">        resultData.setData(data);</span><br><span class="line">        <span class="keyword">return</span> resultData;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; ResultData&lt;T&gt; <span class="title function_">fail</span><span class="params">(<span class="type">int</span> code, String message)</span>&#123;</span><br><span class="line">        ResultData&lt;T&gt; resultData = <span class="keyword">new</span> <span class="title class_">ResultData</span>&lt;&gt;();</span><br><span class="line">        resultData.setStatus(code);</span><br><span class="line">        resultData.setMessage(message);</span><br><span class="line">        <span class="keyword">return</span> resultData;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>ReturnCode类</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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Getter</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> <span class="title class_">ReturnCode</span> &#123;</span><br><span class="line">    RC100(<span class="number">100</span>, <span class="string">&quot;操作成功&quot;</span>),</span><br><span class="line">    RC999(<span class="number">999</span>, <span class="string">&quot;操作失败&quot;</span>),</span><br><span class="line">    RC200(<span class="number">200</span>, <span class="string">&quot;服务开启限流保护，请稍后再试！&quot;</span>),</span><br><span class="line">    RC201(<span class="number">201</span>, <span class="string">&quot;服务开启降级保护，请稍后再试！&quot;</span>),</span><br><span class="line">    RC202(<span class="number">202</span>, <span class="string">&quot;热点参数限流，请稍后再试！&quot;</span>),</span><br><span class="line">    RC203(<span class="number">203</span>, <span class="string">&quot;系统规则不满足要求，请稍后再试！&quot;</span>),</span><br><span class="line">    RC204(<span class="number">204</span>, <span class="string">&quot;系统规则不通过，请稍后再试！&quot;</span>),</span><br><span class="line">    RC403(<span class="number">403</span>, <span class="string">&quot;无访问权限，请联系管理员授予权限&quot;</span>),</span><br><span class="line">    RC401(<span class="number">401</span>, <span class="string">&quot;匿名用户访问无权限资源异常&quot;</span>),</span><br><span class="line">    RC500(<span class="number">500</span>, <span class="string">&quot;系统错误，请稍后重试&quot;</span>),</span><br><span class="line"></span><br><span class="line">    INVALID_TOKEN(<span class="number">2001</span>, <span class="string">&quot;访问令牌不合法&quot;</span>),</span><br><span class="line">    ACCESS_DENIED(<span class="number">2003</span>, <span class="string">&quot;没有权限访问该资源&quot;</span>),</span><br><span class="line">    CLIENT_AUTHENTICATION_FAILED(<span class="number">1001</span>, <span class="string">&quot;客户端认证失败&quot;</span>),</span><br><span class="line">    USERNAME_OR_PASSWORD_ERROR(<span class="number">1002</span>, <span class="string">&quot;用户名或密码错误&quot;</span>),</span><br><span class="line">    UNSUPPORTED_GRANT_TYPE(<span class="number">1003</span>, <span class="string">&quot;不支持的认证模式&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">int</span> code;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> String message;</span><br><span class="line">    ReturnCode(<span class="type">int</span> code, String message)&#123;</span><br><span class="line">        <span class="built_in">this</span>.code = code;</span><br><span class="line">        <span class="built_in">this</span>.message = message;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@RequestMapping(&quot;/product/attr&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ProductController</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Resource</span></span><br><span class="line">    <span class="keyword">private</span> ProductAttrService productAttrService;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@GetMapping(&quot;/info/&#123;attrId&#125;&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> ProductAttr <span class="title function_">getAttrIdById</span><span class="params">(<span class="meta">@PathVariable(&quot;attrId&quot;)</span> Long attrId)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> productAttrService.getById(attrId);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>返回信息：</p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;status&quot;</span><span class="punctuation">:</span> <span class="number">100</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;message&quot;</span><span class="punctuation">:</span> <span class="string">&quot;操作成功&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;data&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;attrId&quot;</span><span class="punctuation">:</span> <span class="number">14</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;attrName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;机身材质工艺&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;searchType&quot;</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;valueType&quot;</span><span class="punctuation">:</span> <span class="number">1</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;icon&quot;</span><span class="punctuation">:</span> <span class="string">&quot;xxx&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;valueSelect&quot;</span><span class="punctuation">:</span> <span class="string">&quot;以官网信息为准;陶瓷;玻璃&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;attrType&quot;</span><span class="punctuation">:</span> <span class="number">1</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;enable&quot;</span><span class="punctuation">:</span> <span class="number">1</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;catelogId&quot;</span><span class="punctuation">:</span> <span class="number">225</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;showDesc&quot;</span><span class="punctuation">:</span> <span class="number">0</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;timestamp&quot;</span><span class="punctuation">:</span> <span class="number">1711606818713</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/java/">java</category>
      
      <category domain="https://b.122345.xyz/categories/java/spring/">spring</category>
      
      
      <category domain="https://b.122345.xyz/tags/spring-boot/">spring-boot</category>
      
      <category domain="https://b.122345.xyz/tags/RestControllerAdvice/">RestControllerAdvice</category>
      
      <category domain="https://b.122345.xyz/tags/%E7%BB%9F%E4%B8%80%E5%A4%84%E7%90%86/">统一处理</category>
      
      
      <comments>https://b.122345.xyz/2024/03/28/springboot%E9%A1%B9%E7%9B%AE%E4%BD%BF%E7%94%A8advice%E5%81%9A%E7%BB%9F%E4%B8%80%E8%BF%94%E5%9B%9E%E5%A4%84%E7%90%86/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>Spring Boot条件注解</title>
      <link>https://b.122345.xyz/2022/07/21/Spring-Boot%E6%9D%A1%E4%BB%B6%E6%B3%A8%E8%A7%A3/</link>
      <guid>https://b.122345.xyz/2022/07/21/Spring-Boot%E6%9D%A1%E4%BB%B6%E6%B3%A8%E8%A7%A3/</guid>
      <pubDate>Thu, 21 Jul 2022 10:46:58 GMT</pubDate>
      
        
        
      <description>&lt;ol&gt;
&lt;li&gt;ConditionalOnBean：是否存在某类或某个名字的Bean&lt;/li&gt;
&lt;li&gt;ConditionalOnMissingBean：是否缺失某个某类或某个名字的Bean&lt;/li&gt;
&lt;li&gt;ConditionalOnSingleCandidate：是否符合指</description>
        
      
      
      
      <content:encoded><![CDATA[<ol><li>ConditionalOnBean：是否存在某类或某个名字的Bean</li><li>ConditionalOnMissingBean：是否缺失某个某类或某个名字的Bean</li><li>ConditionalOnSingleCandidate：是否符合指定类型的Bean只有一个</li><li>ConditionalOnClass：是否存在某个类</li><li>ConditionalOnMissingClass：是否缺失某个类</li><li>ConditionalOnExpression：指定的表达式返回的true还是false</li><li>ConditionalOnJava：判断Java版本</li><li>ConditionalOnJndi：JNDI指定的资源是否存在</li><li>ConditionalOnWebApplication：当前应用是一个Web应用</li><li>ConditionalOnNotWebApplication：当前应用不是一个Web应用</li><li>ConditionalOnProperty：Environment中是否存在某个属性</li><li>ConditionalOnResource：指定的资源是否存在</li><li>ConditionalOnWarDeployment：当前项目是不是以War包部署的方式运行</li><li>ConditionalOnCloudPlatform：是不是在某个云平台上</li></ol>]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/java/">java</category>
      
      <category domain="https://b.122345.xyz/categories/java/spring/">spring</category>
      
      
      <category domain="https://b.122345.xyz/tags/spring/">spring</category>
      
      <category domain="https://b.122345.xyz/tags/spring-boot/">spring-boot</category>
      
      <category domain="https://b.122345.xyz/tags/%E6%B3%A8%E8%A7%A3/">注解</category>
      
      
      <comments>https://b.122345.xyz/2022/07/21/Spring-Boot%E6%9D%A1%E4%BB%B6%E6%B3%A8%E8%A7%A3/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>Spring-Boot属性绑定</title>
      <link>https://b.122345.xyz/2022/07/21/Spring-Boot%E5%B1%9E%E6%80%A7%E7%BB%91%E5%AE%9A/</link>
      <guid>https://b.122345.xyz/2022/07/21/Spring-Boot%E5%B1%9E%E6%80%A7%E7%BB%91%E5%AE%9A/</guid>
      <pubDate>Thu, 21 Jul 2022 10:23:44 GMT</pubDate>
      
        
        
      <description>&lt;h2 id=&quot;PropertySourece&quot;&gt;&lt;a href=&quot;#PropertySourece&quot; class=&quot;headerlink&quot; title=&quot;@PropertySourece()&quot;&gt;&lt;/a&gt;@PropertySourece()&lt;/h2&gt;&lt;p&gt;my.propertie</description>
        
      
      
      
      <content:encoded><![CDATA[<h2 id="PropertySourece"><a href="#PropertySourece" class="headerlink" title="@PropertySourece()"></a>@PropertySourece()</h2><p>my.properties</p><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name</span>=<span class="string">kil</span></span><br></pre></td></tr></table></figure><p>UserService.java</p><p>添加@PropertySource(“my.properties”)指定配置文件 引用@Value(“${name}”)</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.kil.springboot_parameter.service;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Value;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Service;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@program</span>: springboot_parameter</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: UserService</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description</span>:</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: toy</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@create</span>: 2022-07-20 19:51</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="meta">@PropertySource(&quot;my.properties&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Value(&quot;$&#123;name&#125;&quot;)</span></span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.println(name);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>SpringbootParameterApplication.java #Spring启动类</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.kil.springboot_parameter;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> cn.kil.springboot_parameter.service.UserService;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.SpringApplication;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.ConfigurableApplicationContext;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.PropertySource;</span><br><span class="line"></span><br><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">SpringbootParameterApplication</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">ConfigurableApplicationContext</span> <span class="variable">applicationContext</span> <span class="operator">=</span> SpringApplication.run(SpringbootParameterApplication.class, args);</span><br><span class="line">        <span class="type">UserService</span> <span class="variable">bean</span> <span class="operator">=</span> applicationContext.getBean(UserService.class);</span><br><span class="line">        bean.test();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="ConfigurationProperties"><a href="#ConfigurationProperties" class="headerlink" title="@ConfigurationProperties"></a>@ConfigurationProperties</h2><p>@ConfigurationProperties <strong>让开发者将整个配置文件，自动映射到对象中，</strong>比@Value 效率更高</p><p><strong>需要添加@Component注册bean</strong></p><p>属性：</p><ul><li>prefix：可以配置文件属性前缀</li></ul><p>MyProperties.java</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.kil.springboot_parameter.properties;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.context.properties.ConfigurationProperties;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@program</span>: springboot_parameter</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: MyProperties</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description</span>: 我的配置</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: toy</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@create</span>: 2022-07-20 19:50</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="meta">@ConfigurationProperties(prefix = &quot;kil&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MyProperties</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getName</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setName</span><span class="params">(String name)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>UserService.java</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.kil.springboot_parameter.service;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> cn.kil.springboot_parameter.properties.MyProperties;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Service;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@program</span>: springboot_parameter</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: UserService</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description</span>:</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: toy</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@create</span>: 2022-07-20 19:51</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> MyProperties myProperties;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.println(myProperties.getName());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>application.properties</p><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">kil.name</span>=<span class="string">kil</span></span><br></pre></td></tr></table></figure><ul><li>标准用法 配置类**@EnableConfigurationProperties(MyProperties.class)代替@Component**。方便添加条件，可设置多个配置文件</li></ul><p>AppConfig.java</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> cn.kil.springboot_parameter.properties.MyProperties;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.context.properties.EnableConfigurationProperties;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@program</span>: springboot_parameter</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: AppConfig</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description</span>:</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: toy</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@create</span>: 2022-07-20 23:56</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@EnableConfigurationProperties(MyProperties.class)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppConfig</span> &#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li><strong>@ConfigurationPropertiesScan(“cn.kil.springboot_parameter.properties”)</strong> &#x2F;&#x2F;扫描包下的配置文件</li></ul><p>AppConfig.java</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.kil.springboot_parameter;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.context.properties.ConfigurationPropertiesScan;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@program</span>: springboot_parameter</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: AppConfig</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description</span>:</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: toy</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@create</span>: 2022-07-20 23:56</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@ConfigurationPropertiesScan(&quot;cn.kil.springboot_parameter.properties&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppConfig</span> &#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="文件目录信息"><a href="#文件目录信息" class="headerlink" title="文件目录信息"></a>文件目录信息</h2><img src="/2022/07/21/Spring-Boot%E5%B1%9E%E6%80%A7%E7%BB%91%E5%AE%9A/ff506250622363fa0a6b24f8808bac05.png" class="" title="图片[1]-Spring boot属性绑定-TOY论坛">]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/java/">java</category>
      
      <category domain="https://b.122345.xyz/categories/java/spring/">spring</category>
      
      
      <category domain="https://b.122345.xyz/tags/spring/">spring</category>
      
      <category domain="https://b.122345.xyz/tags/spring-boot/">spring-boot</category>
      
      <category domain="https://b.122345.xyz/tags/Properties/">Properties</category>
      
      
      <comments>https://b.122345.xyz/2022/07/21/Spring-Boot%E5%B1%9E%E6%80%A7%E7%BB%91%E5%AE%9A/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>Spring-Boot整合mybatis步骤</title>
      <link>https://b.122345.xyz/2022/07/20/Spring-Boot%E6%95%B4%E5%90%88mybatis%E6%AD%A5%E9%AA%A4/</link>
      <guid>https://b.122345.xyz/2022/07/20/Spring-Boot%E6%95%B4%E5%90%88mybatis%E6%AD%A5%E9%AA%A4/</guid>
      <pubDate>Wed, 20 Jul 2022 10:29:43 GMT</pubDate>
      
        
        
      <description>&lt;h2 id=&quot;添加数据库以及mybatis-maven依赖&quot;&gt;&lt;a href=&quot;#添加数据库以及mybatis-maven依赖&quot; class=&quot;headerlink&quot; title=&quot;添加数据库以及mybatis maven依赖&quot;&gt;&lt;/a&gt;添加数据库以及mybatis maven</description>
        
      
      
      
      <content:encoded><![CDATA[<h2 id="添加数据库以及mybatis-maven依赖"><a href="#添加数据库以及mybatis-maven依赖" class="headerlink" title="添加数据库以及mybatis maven依赖"></a>添加数据库以及mybatis maven依赖</h2><p>jdbc：mybatis包含了spring-boot-starter-jdbc可以不用添加</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></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- mybatis --&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>org.mybatis.spring.boot<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>mybatis-spring-boot-starter<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>2.2.2<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;!-- mysql --&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>mysql<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>mysql-connector-java<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="编写mapper接口和相应的mapper-xml文件"><a href="#编写mapper接口和相应的mapper-xml文件" class="headerlink" title="编写mapper接口和相应的mapper xml文件"></a>编写mapper接口和相应的mapper xml文件</h2><p>UserMapper.java</p><p>如果不添加@Mapper注解可以在SpringMybatisApplication.java也就是springboot启动类添加@MapperScan(“cn.kil.springboot_mybatis.mapper”)注解指定mapper接口的扫描路径。</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.kil.springboot_mybatis.mapper;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> cn.kil.springboot_mybatis.pojo.User;</span><br><span class="line"><span class="keyword">import</span> org.apache.ibatis.annotations.Mapper;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Mapper</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">UserMapper</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;User&gt; <span class="title function_">getAllUserList</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>UserMapper.xml</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></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span> ?&gt;</span></span><br><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">mapper</span></span></span><br><span class="line"><span class="meta">        <span class="keyword">PUBLIC</span> <span class="string">&quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;</span></span></span><br><span class="line"><span class="meta">        <span class="string">&quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 绑定mapper接口 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">mapper</span> <span class="attr">namespace</span>=<span class="string">&quot;cn.kil.springboot_mybatis.mapper.UserMapper&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;getAllUserList&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;user&quot;</span>&gt;</span></span><br><span class="line">        select * from kivm.k_users</span><br><span class="line">    <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">mapper</span>&gt;</span></span><br></pre></td></tr></table></figure><p>附加相应的实体类信息User</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><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.kil.springboot_mybatis.pojo;</span><br><span class="line"></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="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@program</span>: kivm</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: User</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description</span>: 用户</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: toy</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@create</span>: 2022-05-19 20:00</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">User</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> uid;</span><br><span class="line">    <span class="keyword">private</span> String username;</span><br><span class="line">    <span class="keyword">private</span> String password;</span><br><span class="line">    <span class="keyword">private</span> String email;</span><br><span class="line">    <span class="keyword">private</span> String phone;</span><br><span class="line">    <span class="keyword">private</span> String icon;</span><br><span class="line">    <span class="keyword">private</span> Date createTime;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> status;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">User</span><span class="params">()</span> &#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">User</span><span class="params">(<span class="type">int</span> uid, String username, String password, String email, String phone, String icon, Date createTime, <span class="type">int</span> status)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.uid = uid;</span><br><span class="line">        <span class="built_in">this</span>.username = username;</span><br><span class="line">        <span class="built_in">this</span>.password = password;</span><br><span class="line">        <span class="built_in">this</span>.email = email;</span><br><span class="line">        <span class="built_in">this</span>.phone = phone;</span><br><span class="line">        <span class="built_in">this</span>.icon = icon;</span><br><span class="line">        <span class="built_in">this</span>.createTime = createTime;</span><br><span class="line">        <span class="built_in">this</span>.status = status;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">getUid</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> uid;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setUid</span><span class="params">(<span class="type">int</span> uid)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.uid = uid;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getUsername</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> username;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setUsername</span><span class="params">(String username)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.username = username;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getPassword</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> password;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setPassword</span><span class="params">(String password)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.password = password;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getEmail</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> email;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setEmail</span><span class="params">(String email)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.email = email;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getPhone</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> phone;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setPhone</span><span class="params">(String phone)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.phone = phone;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getIcon</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> icon;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setIcon</span><span class="params">(String icon)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.icon = icon;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> Date <span class="title function_">getCreateTime</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> createTime;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setCreateTime</span><span class="params">(Date createTime)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.createTime = createTime;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">getStatus</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> status;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setStatus</span><span class="params">(<span class="type">int</span> status)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.status = status;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">toString</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;User&#123;&quot;</span> +</span><br><span class="line">                <span class="string">&quot;uid=&quot;</span> + uid +</span><br><span class="line">                <span class="string">&quot;, username=&#x27;&quot;</span> + username + <span class="string">&#x27;\&#x27;&#x27;</span> +</span><br><span class="line">                <span class="string">&quot;, password=&#x27;&quot;</span> + password + <span class="string">&#x27;\&#x27;&#x27;</span> +</span><br><span class="line">                <span class="string">&quot;, email=&#x27;&quot;</span> + email + <span class="string">&#x27;\&#x27;&#x27;</span> +</span><br><span class="line">                <span class="string">&quot;, phone=&#x27;&quot;</span> + phone + <span class="string">&#x27;\&#x27;&#x27;</span> +</span><br><span class="line">                <span class="string">&quot;, icon=&#x27;&quot;</span> + icon + <span class="string">&#x27;\&#x27;&#x27;</span> +</span><br><span class="line">                <span class="string">&quot;, createTime=&quot;</span> + createTime +</span><br><span class="line">                <span class="string">&quot;, status=&quot;</span> + status +</span><br><span class="line">                <span class="string">&#x27;&#125;&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="编辑spring配置文件application-properties添加数据库以及Mapper-xml信息"><a href="#编辑spring配置文件application-properties添加数据库以及Mapper-xml信息" class="headerlink" title="编辑spring配置文件application.properties添加数据库以及Mapper xml信息"></a>编辑spring配置文件application.properties添加数据库以及Mapper xml信息</h2><figure class="highlight properties"><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="attr">spring</span>:<span class="string"></span></span><br><span class="line">  <span class="attr">datasource</span>:<span class="string"></span></span><br><span class="line">    <span class="attr">url</span>: <span class="string">jdbc:mysql://localhost:3306/kivm?useSSl=true&amp;useUnicode=true&amp;characterEnding=utf8&amp;serverTimezone=Asia/Shanghai</span></span><br><span class="line">    <span class="attr">username</span>: <span class="string">root</span></span><br><span class="line">    <span class="attr">password</span>: <span class="string">123456</span></span><br><span class="line">    <span class="attr">driver-class-name</span>: <span class="string">com.mysql.cj.jdbc.Driver</span></span><br><span class="line"><span class="attr">mybatis</span>:<span class="string"></span></span><br><span class="line">  <span class="attr">mapper-locations</span>: <span class="string">classpath:cn/kil/springboot_mybatis/mapper/*Mapper.xml #mapper文件路径</span></span><br><span class="line">  <span class="attr">type-aliases-package</span>: <span class="string">cn.kil.springboot_mybatis.pojo #实体类别名</span></span><br></pre></td></tr></table></figure><h2 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h2><img src="/2022/07/20/Spring-Boot%E6%95%B4%E5%90%88mybatis%E6%AD%A5%E9%AA%A4/216d4ecab590eb4ab4388d652291fddd-1024x171.png" class="" title="图片[1]-Spring boot整合mybatis步骤-TOY论坛"><p>附加项目的文件目录信息</p><img src="/2022/07/20/Spring-Boot%E6%95%B4%E5%90%88mybatis%E6%AD%A5%E9%AA%A4/45a7ae49c5182e5ed194823a5c86d453.png" class="" title="图片[2]-Spring boot整合mybatis步骤-TOY论坛"><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><ol><li>添加数据库连接信息</li><li>设置@Mapper注解或者指定@MapperScan注解扫描的包路径</li><li>指定mapper-locations的路径</li></ol>]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/java/">java</category>
      
      <category domain="https://b.122345.xyz/categories/java/spring/">spring</category>
      
      
      <category domain="https://b.122345.xyz/tags/spring/">spring</category>
      
      <category domain="https://b.122345.xyz/tags/spring-boot/">spring-boot</category>
      
      <category domain="https://b.122345.xyz/tags/mybatis/">mybatis</category>
      
      
      <comments>https://b.122345.xyz/2022/07/20/Spring-Boot%E6%95%B4%E5%90%88mybatis%E6%AD%A5%E9%AA%A4/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>JAVA之自动装配</title>
      <link>https://b.122345.xyz/2022/07/17/JAVA%E4%B9%8B%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D/</link>
      <guid>https://b.122345.xyz/2022/07/17/JAVA%E4%B9%8B%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D/</guid>
      <pubDate>Sun, 17 Jul 2022 10:33:57 GMT</pubDate>
      
        
        
      <description>&lt;p&gt;&lt;strong&gt;级联属性赋值&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在&lt;bean&gt;的&lt;property&gt;子元素中，为它所依赖的Bean的属性进行赋值，这就是所谓的”级联属性赋值”。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用级联属性赋值注意事项：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;l</description>
        
      
      
      
      <content:encoded><![CDATA[<p><strong>级联属性赋值</strong></p><p>在<bean>的<property>子元素中，为它所依赖的Bean的属性进行赋值，这就是所谓的”级联属性赋值”。</p><p><strong>使用级联属性赋值注意事项：</strong></p><ol><li>java类中必须有setter方法</li><li>java类中必须有无参构造器(默认存在）</li><li>依赖其他Bean的类中，必须提供一个它依赖的Bean的getXxx()方法</li></ol><p>Spring在Bean与Bean之间建立依赖关系的行为成为装配。Spring的IOC容器虽然强大，但本身不过是一个空壳，需要主动将Bean放进去，并告诉它Bean和Bean之间的依赖关系，才能按照我们的要求完成装配工作。</p><p><strong>spring通过注解实现自动装配的步骤如下：</strong></p><p><strong>1.引入依赖</strong></p><p><strong>2.开启组件扫描</strong></p><p>Spring默认不使用注解装配Bean。因此在Spring XML配置中，通过元素开启Spring Beans的自动扫描功能，即在类上使用了@Component注解，就将该类装配到容器中。</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></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">    &lt;!<span class="attr">--添加context相关的约束--</span>&gt;</span></span><br><span class="line">       xmlns:context=&quot;http://www.springframework.org/schema/context&quot;</span><br><span class="line">       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans</span><br><span class="line">    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd</span><br><span class="line">    http://www.springframework.org/schema/context</span><br><span class="line">            http://www.springframework.org/schema/context/spring-context.xsd&quot;&gt;</span><br><span class="line">    <span class="comment">&lt;!--开启组件扫描功能--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">context:component-scan</span> <span class="attr">base-package</span>=<span class="string">&quot;net.biancheng.c&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">context:component-scan</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure><p><strong>3.使用注解定义Bean</strong></p><p>Spring提供了多个注解，在不同类的层次下，使用不同的注解，将他们定义为Spring Bean。</p><img src="/2022/07/17/JAVA%E4%B9%8B%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D/dfdfeb4ccd8422ff7251614a01418340.webp" class="" title="图片[1]-JAVA之自动装配-TOY论坛"><p><strong>4.基于注解方式实现依赖注入</strong></p><img src="/2022/07/17/JAVA%E4%B9%8B%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D/dfdfeb4ccd8422ff7251614a01418340.webp" class="" title="图片[2]-JAVA之自动装配-TOY论坛">]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/java/">java</category>
      
      
      <category domain="https://b.122345.xyz/tags/java/">java</category>
      
      <category domain="https://b.122345.xyz/tags/spring/">spring</category>
      
      <category domain="https://b.122345.xyz/tags/spring-boot/">spring-boot</category>
      
      <category domain="https://b.122345.xyz/tags/spring-mvc/">spring mvc</category>
      
      
      <comments>https://b.122345.xyz/2022/07/17/JAVA%E4%B9%8B%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>SSM配置MyBatis步骤</title>
      <link>https://b.122345.xyz/2022/07/16/SSM%E9%85%8D%E7%BD%AEMyBatis%E6%AD%A5%E9%AA%A4/</link>
      <guid>https://b.122345.xyz/2022/07/16/SSM%E9%85%8D%E7%BD%AEMyBatis%E6%AD%A5%E9%AA%A4/</guid>
      <pubDate>Sat, 16 Jul 2022 10:48:54 GMT</pubDate>
      
        
        
      <description>&lt;h2 id=&quot;1-添加所需maven依赖&quot;&gt;&lt;a href=&quot;#1-添加所需maven依赖&quot; class=&quot;headerlink&quot; title=&quot;1.添加所需maven依赖&quot;&gt;&lt;/a&gt;1.添加所需maven依赖&lt;/h2&gt;&lt;p&gt;maven仓库：&lt;a href=&quot;https://b</description>
        
      
      
      
      <content:encoded><![CDATA[<h2 id="1-添加所需maven依赖"><a href="#1-添加所需maven依赖" class="headerlink" title="1.添加所需maven依赖"></a>1.添加所需maven依赖</h2><p>maven仓库：<a href="https://blog.122345.xyz/?golink=aHR0cHM6Ly9tdm5yZXBvc2l0b3J5LmNvbS8=">https://mvnrepository.com/</a></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></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--Mybatis--&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>org.mybatis<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>mybatis<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>3.5.9<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 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>org.mybatis<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>mybatis-spring<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>2.0.7<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;!--数据库驱动--&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>mysql<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>mysql-connector-java<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>8.0.29<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></pre></td></tr></table></figure><h2 id="2-resources目录新建mybatis-config-xml文件"><a href="#2-resources目录新建mybatis-config-xml文件" class="headerlink" title="2.resources目录新建mybatis-config.xml文件"></a>2.resources目录新建mybatis-config.xml文件</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span> ?&gt;</span></span><br><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">configuration</span></span></span><br><span class="line"><span class="meta">        <span class="keyword">PUBLIC</span> <span class="string">&quot;-//mybatis.org//DTD Config 3.0//EN&quot;</span></span></span><br><span class="line"><span class="meta">        <span class="string">&quot;http://mybatis.org/dtd/mybatis-3-config.dtd&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--日志--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">settings</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">setting</span> <span class="attr">name</span>=<span class="string">&quot;logImpl&quot;</span> <span class="attr">value</span>=<span class="string">&quot;STDOUT_LOGGING&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">setting</span> <span class="attr">name</span>=<span class="string">&quot;mapUnderscoreToCamelCase&quot;</span> <span class="attr">value</span>=<span class="string">&quot;true&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">settings</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--实体类别名扫描--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">typeAliases</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">package</span> <span class="attr">name</span>=<span class="string">&quot;cn.kil.pojo&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">typeAliases</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--注册mapper</span></span><br><span class="line"><span class="comment">     这种方式配置的，需要</span></span><br><span class="line"><span class="comment">　　    1. 所写的xml配置文件和接口在同一包下（在resources下创建和接口相同的路径名也是一样的【注意：创建路径需要用“/”分割，而不是“.”】）</span></span><br><span class="line"><span class="comment">　　    2. 在xml配置中的namespace要和接口的全类名一样，id和接口中的方法名一样，parameterType 和接口中方法形参一直。</span></span><br><span class="line"><span class="comment">     --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">mappers</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">package</span> <span class="attr">name</span>=<span class="string">&quot;cn.kil.dao&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">mappers</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="2-resources目录新建db-properties文件"><a href="#2-resources目录新建db-properties文件" class="headerlink" title="2.resources目录新建db.properties文件"></a>2.resources目录新建db.properties文件</h2><figure class="highlight properties"><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></pre></td><td class="code"><pre><span class="line"><span class="attr">jdbc.driver</span>=<span class="string">com.mysql.cj.jdbc.Driver</span></span><br><span class="line"><span class="attr">jdbc.url</span>=<span class="string">jdbc:mysql://localhost:3306/kivm?useSSl=true&amp;useUnicode=true&amp;characterEnding=utf8&amp;serverTimezone=Asia/Shanghai</span></span><br><span class="line"><span class="attr">jdbc.username</span>=<span class="string">root</span></span><br><span class="line"><span class="attr">jdbc.password</span>=<span class="string">123456</span></span><br></pre></td></tr></table></figure><h2 id="3-配置spring-dao-xml配置文件"><a href="#3-配置spring-dao-xml配置文件" class="headerlink" title="3.配置spring-dao.xml配置文件"></a>3.配置spring-dao.xml配置文件</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:context</span>=<span class="string">&quot;http://www.springframework.org/schema/context&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:aop</span>=<span class="string">&quot;http://www.springframework.org/schema/aop&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="string"><span class="tag">                            http://www.springframework.org/schema/beans/spring-beans.xsd</span></span></span><br><span class="line"><span class="string"><span class="tag">                            http://www.springframework.org/schema/context</span></span></span><br><span class="line"><span class="string"><span class="tag">                            http://www.springframework.org/schema/context/spring-context.xsd</span></span></span><br><span class="line"><span class="string"><span class="tag">                            http://www.springframework.org/schema/aop</span></span></span><br><span class="line"><span class="string"><span class="tag">                            http://www.springframework.org/schema/aop/spring-aop.xsd&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--导入数据库连接配置文件--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">context:property-placeholder</span> <span class="attr">location</span>=<span class="string">&quot;classpath:db.properties&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--数据库链接池--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.springframework.jdbc.datasource.DriverManagerDataSource&quot;</span> <span class="attr">id</span>=<span class="string">&quot;dataSource&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;driverClassName&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;jdbc.driver&#125;&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;url&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;jdbc.url&#125;&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;username&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;jdbc.username&#125;&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;password&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;jdbc.password&#125;&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--获取SqlSessionFactory--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.mybatis.spring.SqlSessionFactoryBean&quot;</span> <span class="attr">id</span>=<span class="string">&quot;sqlSessionFactory&quot;</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--引入数据库连接池--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dataSource&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;dataSource&quot;</span>/&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--绑定mybatis配置文件--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;configLocation&quot;</span> <span class="attr">value</span>=<span class="string">&quot;classpath:mybatis-config.xml&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--mapper自动扫描 Mapper静态代理--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.mybatis.spring.mapper.MapperScannerConfigurer&quot;</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--引入SqlSessionFactory--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;sqlSessionFactoryBeanName&quot;</span> <span class="attr">value</span>=<span class="string">&quot;sqlSessionFactory&quot;</span>/&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--扫描的包--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;basePackage&quot;</span> <span class="attr">value</span>=<span class="string">&quot;cn.kil.dao&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure><p>接下来就能愉快的编写mapper和接口了。当然要把mapper文件放在你扫描的包下</p><h2 id="项目结构"><a href="#项目结构" class="headerlink" title="项目结构"></a>项目结构</h2><img src="/2022/07/16/SSM%E9%85%8D%E7%BD%AEMyBatis%E6%AD%A5%E9%AA%A4/4f037f483d5cb49001cfff7986169931.png" class="" title="图片[1]-SSM配置MyBatis步骤-TOY论坛">]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/java/">java</category>
      
      <category domain="https://b.122345.xyz/categories/java/spring/">spring</category>
      
      
      <category domain="https://b.122345.xyz/tags/java/">java</category>
      
      <category domain="https://b.122345.xyz/tags/spring/">spring</category>
      
      <category domain="https://b.122345.xyz/tags/spring-mvc/">spring-mvc</category>
      
      <category domain="https://b.122345.xyz/tags/ssm/">ssm</category>
      
      
      <comments>https://b.122345.xyz/2022/07/16/SSM%E9%85%8D%E7%BD%AEMyBatis%E6%AD%A5%E9%AA%A4/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>node定时发送html格式邮件，带模板引擎编辑动态编辑html</title>
      <link>https://b.122345.xyz/2022/07/16/node%E5%AE%9A%E6%97%B6%E5%8F%91%E9%80%81html%E6%A0%BC%E5%BC%8F%E9%82%AE%E4%BB%B6%EF%BC%8C%E5%B8%A6%E6%A8%A1%E6%9D%BF%E5%BC%95%E6%93%8E%E7%BC%96%E8%BE%91%E5%8A%A8%E6%80%81%E7%BC%96%E8%BE%91html/</link>
      <guid>https://b.122345.xyz/2022/07/16/node%E5%AE%9A%E6%97%B6%E5%8F%91%E9%80%81html%E6%A0%BC%E5%BC%8F%E9%82%AE%E4%BB%B6%EF%BC%8C%E5%B8%A6%E6%A8%A1%E6%9D%BF%E5%BC%95%E6%93%8E%E7%BC%96%E8%BE%91%E5%8A%A8%E6%80%81%E7%BC%96%E8%BE%91html/</guid>
      <pubDate>Sat, 16 Jul 2022 10:20:40 GMT</pubDate>
      
        
        
      <description>&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;l</description>
        
      
      
      
      <content:encoded><![CDATA[<figure class="highlight js"><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><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//引用模块</span></span><br><span class="line"><span class="keyword">const</span> nodemailer = <span class="built_in">require</span>(<span class="string">&quot;nodemailer&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> schedule = <span class="built_in">require</span>(<span class="string">&quot;node-schedule&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">&quot;path&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> template = <span class="built_in">require</span>(<span class="string">&quot;art-template&quot;</span>);</span><br><span class="line"><span class="comment">//模板路径</span></span><br><span class="line"><span class="keyword">const</span> views = path.<span class="title function_">join</span>(__dirname, <span class="string">&quot;config&quot;</span>, <span class="string">&quot;index.art&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//时间差</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">getDatetime</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> date1 = <span class="string">&quot;2022/03/17 00:00:00&quot;</span>; <span class="comment">//以往时间</span></span><br><span class="line">    <span class="keyword">var</span> date2 = <span class="keyword">new</span> <span class="title class_">Date</span>(); <span class="comment">//当前时间</span></span><br><span class="line">    <span class="keyword">var</span> date3 = date2.<span class="title function_">getTime</span>() - <span class="keyword">new</span> <span class="title class_">Date</span>(date1).<span class="title function_">getTime</span>(); <span class="comment">//时间差的毫秒数</span></span><br><span class="line">    <span class="comment">//计算出相差天数</span></span><br><span class="line">    <span class="keyword">var</span> days = <span class="title class_">Math</span>.<span class="title function_">floor</span>(date3 / (<span class="number">24</span> * <span class="number">3600</span> * <span class="number">1000</span>));</span><br><span class="line">    <span class="comment">//计算出小时数</span></span><br><span class="line">    <span class="keyword">var</span> leave1 = date3 % (<span class="number">24</span> * <span class="number">3600</span> * <span class="number">1000</span>); <span class="comment">//计算天数后剩余的毫秒数</span></span><br><span class="line">    <span class="keyword">var</span> hours = <span class="title class_">Math</span>.<span class="title function_">floor</span>(leave1 / (<span class="number">3600</span> * <span class="number">1000</span>));</span><br><span class="line">    <span class="comment">//计算相差分钟数</span></span><br><span class="line">    <span class="keyword">var</span> leave2 = leave1 % (<span class="number">3600</span> * <span class="number">1000</span>); <span class="comment">//计算小时数后剩余的毫秒数</span></span><br><span class="line">    <span class="keyword">var</span> minutes = <span class="title class_">Math</span>.<span class="title function_">floor</span>(leave2 / (<span class="number">60</span> * <span class="number">1000</span>));</span><br><span class="line">    <span class="comment">//计算相差秒数</span></span><br><span class="line">    <span class="keyword">var</span> leave3 = leave2 % (<span class="number">60</span> * <span class="number">1000</span>); <span class="comment">//计算分钟数后剩余的毫秒数</span></span><br><span class="line">    <span class="keyword">var</span> seconds = <span class="title class_">Math</span>.<span class="title function_">round</span>(leave3 / <span class="number">1000</span>);</span><br><span class="line">    <span class="title function_">j_content</span>(days);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//html模板配置</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">j_content</span>(<span class="params">jdatetime</span>) &#123;</span><br><span class="line">    <span class="comment">//const j_days=</span></span><br><span class="line">    <span class="keyword">const</span> html = <span class="title function_">template</span>(views, &#123;</span><br><span class="line">        <span class="attr">namea</span>: <span class="string">&quot;你&quot;</span>,</span><br><span class="line">        <span class="attr">nameb</span>: <span class="string">&quot;她&quot;</span>,</span><br><span class="line">        <span class="attr">datetime</span>: jdatetime,</span><br><span class="line">        <span class="title class_">Signature</span>: <span class="string">&quot;xxxxxx&quot;</span>,</span><br><span class="line">    &#125;);</span><br><span class="line"></span><br><span class="line">    <span class="title function_">j_email</span>(html);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//邮箱配置</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">j_email</span>(<span class="params">content</span>) &#123;</span><br><span class="line">    <span class="keyword">const</span> email = nodemailer.<span class="title function_">createTransport</span>(&#123;</span><br><span class="line">        <span class="attr">service</span>: <span class="string">&quot;xxxxxxx@qq.com&quot;</span>, <span class="comment">//你的邮箱</span></span><br><span class="line">        <span class="attr">secure</span>: <span class="literal">true</span>,</span><br><span class="line">        <span class="attr">auth</span>: &#123;</span><br><span class="line">            <span class="attr">user</span>: <span class="string">&quot;xxxxxxx@qq.com&quot;</span>, <span class="comment">//你的邮箱</span></span><br><span class="line">            <span class="attr">pass</span>: <span class="string">&quot;自己邮箱账户申请&quot;</span>, <span class="comment">//你的邮箱授权码</span></span><br><span class="line">        &#125;,</span><br><span class="line">    &#125;);</span><br><span class="line"></span><br><span class="line">    email.<span class="title function_">sendMail</span>(</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="attr">from</span>: <span class="string">&quot;11949420@qq.com&quot;</span>, <span class="comment">//你的邮箱</span></span><br><span class="line">            <span class="attr">subject</span>: <span class="string">&quot;久伴私信你&quot;</span>,</span><br><span class="line">            <span class="attr">to</span>: <span class="string">&quot;xxxxxxx@qq.com&quot;</span>, <span class="comment">//对方邮箱</span></span><br><span class="line">            <span class="attr">html</span>: content,</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="function">(<span class="params">err, data</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (err) &#123;</span><br><span class="line">                <span class="variable language_">console</span>.<span class="title function_">error</span>(<span class="string">&quot;发送失败&quot;</span> + err);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;发送成功&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//定时发送</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">getTime</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> rule = <span class="keyword">new</span> schedule.<span class="title class_">RecurrenceRule</span>();</span><br><span class="line">    rule.<span class="property">dayOfWeek</span> = [<span class="number">0</span>, <span class="keyword">new</span> schedule.<span class="title class_">Range</span>(<span class="number">1</span>, <span class="number">6</span>)];</span><br><span class="line">    rule.<span class="property">hour</span> = <span class="number">21</span>;</span><br><span class="line">    rule.<span class="property">minute</span> = <span class="number">30</span>;</span><br><span class="line">    <span class="keyword">var</span> j = schedule.<span class="title function_">scheduleJob</span>(rule, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;执行任务&quot;</span>);</span><br><span class="line">        <span class="title function_">getDatetime</span>();</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">getTime</span>();</span><br></pre></td></tr></table></figure>]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/Node-js/">Node.js</category>
      
      
      <category domain="https://b.122345.xyz/tags/web%E5%89%8D%E7%AB%AF/">web前端</category>
      
      <category domain="https://b.122345.xyz/tags/Node-js/">Node.js</category>
      
      <category domain="https://b.122345.xyz/tags/%E9%82%AE%E4%BB%B6/">邮件</category>
      
      
      <comments>https://b.122345.xyz/2022/07/16/node%E5%AE%9A%E6%97%B6%E5%8F%91%E9%80%81html%E6%A0%BC%E5%BC%8F%E9%82%AE%E4%BB%B6%EF%BC%8C%E5%B8%A6%E6%A8%A1%E6%9D%BF%E5%BC%95%E6%93%8E%E7%BC%96%E8%BE%91%E5%8A%A8%E6%80%81%E7%BC%96%E8%BE%91html/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>JSON Web Token 入门教程</title>
      <link>https://b.122345.xyz/2022/07/15/JSON-Web-Token-%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/</link>
      <guid>https://b.122345.xyz/2022/07/15/JSON-Web-Token-%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/</guid>
      <pubDate>Fri, 15 Jul 2022 10:51:45 GMT</pubDate>
      
        
        
      <description>&lt;p&gt;JSON Web Token（缩写 JWT）是目前最流行的跨域认证解决方案，本文介绍它的原理和用法。&lt;/p&gt;
&lt;img src=&quot;/2022/07/15/JSON-Web-Token-%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/0451838a</description>
        
      
      
      
      <content:encoded><![CDATA[<p>JSON Web Token（缩写 JWT）是目前最流行的跨域认证解决方案，本文介绍它的原理和用法。</p><img src="/2022/07/15/JSON-Web-Token-%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/0451838a273b7e513ec72e1bfeb9bea4.jpg" class="" title="图片[1]-JSON Web Token 入门教程-TOY论坛"><h2 id="一、跨域认证的问题"><a href="#一、跨域认证的问题" class="headerlink" title="一、跨域认证的问题"></a>一、跨域认证的问题</h2><p>互联网服务离不开用户认证。一般流程是下面这样。</p><blockquote><p>1、用户向服务器发送用户名和密码。</p><p>2、服务器验证通过后，在当前对话（session）里面保存相关数据，比如用户角色、登录时间等等。</p><p>3、服务器向用户返回一个 session_id，写入用户的 Cookie。</p><p>4、用户随后的每一次请求，都会通过 Cookie，将 session_id 传回服务器。</p><p>5、服务器收到 session_id，找到前期保存的数据，由此得知用户的身份。</p></blockquote><p>这种模式的问题在于，扩展性（scaling）不好。单机当然没有问题，如果是服务器集群，或者是跨域的服务导向架构，就要求 session 数据共享，每台服务器都能够读取 session。</p><p>举例来说，A 网站和 B 网站是同一家公司的关联服务。现在要求，用户只要在其中一个网站登录，再访问另一个网站就会自动登录，请问怎么实现？</p><p>一种解决方案是 session 数据持久化，写入数据库或别的持久层。各种服务收到请求后，都向持久层请求数据。这种方案的优点是架构清晰，缺点是工程量比较大。另外，持久层万一挂了，就会单点失败。</p><p>另一种方案是服务器索性不保存 session 数据了，所有数据都保存在客户端，每次请求都发回服务器。JWT 就是这种方案的一个代表。</p><h2 id="二、JWT-的原理"><a href="#二、JWT-的原理" class="headerlink" title="二、JWT 的原理"></a>二、JWT 的原理</h2><p>JWT 的原理是，服务器认证以后，生成一个 JSON 对象，发回给用户，就像下面这样。</p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;姓名&quot;</span><span class="punctuation">:</span> <span class="string">&quot;张三&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;角色&quot;</span><span class="punctuation">:</span> <span class="string">&quot;管理员&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;到期时间&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2018年7月1日0点0分&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>以后，用户与服务端通信的时候，都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据，服务器在生成这个对象的时候，会加上签名（详见后文）。</p><p>服务器就不保存任何 session 数据了，也就是说，服务器变成无状态了，从而比较容易实现扩展。</p><h2 id="三、JWT-的数据结构"><a href="#三、JWT-的数据结构" class="headerlink" title="三、JWT 的数据结构"></a>三、JWT 的数据结构</h2><p>实际的 JWT 大概就像下面这样。</p><img src="/2022/07/15/JSON-Web-Token-%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/85c78f787f1ef0ae4e6fb9182f67cc4f.jpg" class="" title="图片[2]-JSON Web Token 入门教程-TOY论坛"><p>它是一个很长的字符串，中间用点（<code>.</code>）分隔成三个部分。注意，JWT 内部是没有换行的，这里只是为了便于展示，将它写成了几行。</p><p>JWT 的三个部分依次如下。</p><ul><li>Header（头部）</li><li>Payload（负载）</li><li>Signature（签名）</li></ul><p>写成一行，就是下面的样子。</p><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">Header.Payload.Signature</span></span><br></pre></td></tr></table></figure><img src="/2022/07/15/JSON-Web-Token-%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/3a0b76eb607d4c4a28e093cc66bf1b4e.jpg" class="" title="图片[3]-JSON Web Token 入门教程-TOY论坛"><p>下面依次介绍这三个部分。</p><h3 id="3-1-Header"><a href="#3-1-Header" class="headerlink" title="3.1 Header"></a>3.1 Header</h3><p>Header 部分是一个 JSON 对象，描述 JWT 的元数据，通常是下面的样子。</p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;alg&quot;</span><span class="punctuation">:</span> <span class="string">&quot;HS256&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;typ&quot;</span><span class="punctuation">:</span> <span class="string">&quot;JWT&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>上面代码中，<code>alg</code>属性表示签名的算法（algorithm），默认是 HMAC SHA256（写成 HS256）；<code>typ</code>属性表示这个令牌（token）的类型（type），JWT 令牌统一写为<code>JWT</code>。</p><p>最后，将上面的 JSON 对象使用 Base64URL 算法（详见后文）转成字符串。</p><h3 id="3-2-Payload"><a href="#3-2-Payload" class="headerlink" title="3.2 Payload"></a>3.2 Payload</h3><p>Payload 部分也是一个 JSON 对象，用来存放实际需要传递的数据。JWT 规定了7个官方字段，供选用。</p><ul><li>iss (issuer)：签发人</li><li>exp (expiration time)：过期时间</li><li>sub (subject)：主题</li><li>aud (audience)：受众</li><li>nbf (Not Before)：生效时间</li><li>iat (Issued At)：签发时间</li><li>jti (JWT ID)：编号</li></ul><p>除了官方字段，你还可以在这个部分定义私有字段，下面就是一个例子。</p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;sub&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1234567890&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;John Doe&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;admin&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>注意，JWT 默认是不加密的，任何人都可以读到，所以不要把秘密信息放在这个部分。</p><p>这个 JSON 对象也要使用 Base64URL 算法转成字符串。</p><h3 id="3-3-Signature"><a href="#3-3-Signature" class="headerlink" title="3.3 Signature"></a>3.3 Signature</h3><p>Signature 部分是对前两部分的签名，防止数据篡改。</p><p>首先，需要指定一个密钥（secret）。这个密钥只有服务器才知道，不能泄露给用户。然后，使用 Header 里面指定的签名算法（默认是 HMAC SHA256），按照下面的公式产生签名。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="title class_">HMACSHA256</span>(</span><br><span class="line">  <span class="title function_">base64UrlEncode</span>(header) + <span class="string">&quot;.&quot;</span> +</span><br><span class="line">  <span class="title function_">base64UrlEncode</span>(payload),</span><br><span class="line">  secret)</span><br></pre></td></tr></table></figure><p>算出签名以后，把 Header、Payload、Signature 三个部分拼成一个字符串，每个部分之间用”点”（<code>.</code>）分隔，就可以返回给用户。</p><h3 id="3-4-Base64URL"><a href="#3-4-Base64URL" class="headerlink" title="3.4 Base64URL"></a>3.4 Base64URL</h3><p>前面提到，Header 和 Payload 串型化的算法是 Base64URL。这个算法跟 Base64 算法基本类似，但有一些小的不同。</p><p>JWT 作为一个令牌（token），有些场合可能会放到 URL（比如 api.example.com&#x2F;?token&#x3D;xxx）。Base64 有三个字符<code>+</code>、<code>/</code>和<code>=</code>，在 URL 里面有特殊含义，所以要被替换掉：<code>=</code>被省略、<code>+</code>替换成<code>-</code>，<code>/</code>替换成<code>_</code> 。这就是 Base64URL 算法。</p><h2 id="四、JWT-的使用方式"><a href="#四、JWT-的使用方式" class="headerlink" title="四、JWT 的使用方式"></a>四、JWT 的使用方式</h2><p>客户端收到服务器返回的 JWT，可以储存在 Cookie 里面，也可以储存在 localStorage。</p><p>此后，客户端每次与服务器通信，都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送，但是这样不能跨域，所以更好的做法是放在 HTTP 请求的头信息<code>Authorization</code>字段里面。</p><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">Authorization</span>: <span class="string">Bearer &lt;token&gt;</span></span><br></pre></td></tr></table></figure><p>另一种做法是，跨域的时候，JWT 就放在 POST 请求的数据体里面。</p><h2 id="五、JWT-的几个特点"><a href="#五、JWT-的几个特点" class="headerlink" title="五、JWT 的几个特点"></a>五、JWT 的几个特点</h2><p>（1）JWT 默认是不加密，但也是可以加密的。生成原始 Token 以后，可以用密钥再加密一次。</p><p>（2）JWT 不加密的情况下，不能将秘密数据写入 JWT。</p><p>（3）JWT 不仅可以用于认证，也可以用于交换信息。有效使用 JWT，可以降低服务器查询数据库的次数。</p><p>（4）JWT 的最大缺点是，由于服务器不保存 session 状态，因此无法在使用过程中废止某个 token，或者更改 token 的权限。也就是说，一旦 JWT 签发了，在到期之前就会始终有效，除非服务器部署额外的逻辑。</p><p>（5）JWT 本身包含了认证信息，一旦泄露，任何人都可以获得该令牌的所有权限。为了减少盗用，JWT 的有效期应该设置得比较短。对于一些比较重要的权限，使用时应该再次对用户进行认证。</p><p>（6）为了减少盗用，JWT 不应该使用 HTTP 协议明码传输，要使用 HTTPS 协议传输。</p><h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><ul><li><a href="https://blog.122345.xyz/?golink=aHR0cHM6Ly9qd3QuaW8vaW50cm9kdWN0aW9uLw==">Introduction to JSON Web Tokens</a>， by Auth0</li><li><a href="https://blog.122345.xyz/?golink=aHR0cHM6Ly9tZWRpdW0uY29tL0Bicnlhbm1hbnVlbGUvc2Vzc2lvbmxlc3MtYXV0aGVudGljYXRpb24td2l0aGUtand0cy13aXRoLW5vZGUtZXhwcmVzcy1wYXNzcG9ydC1qcy02OWIwNTllNGIyMmM=">Sessionless Authentication using JWTs (with Node + Express + Passport JS)</a>, by Bryan Manuele</li><li><a href="https://blog.122345.xyz/?golink=aHR0cHM6Ly9naXRodWIuY29tL2R3eWwvbGVhcm4tanNvbi13ZWItdG9rZW5zL2Jsb2IvbWFzdGVyL1JFQURNRS5tZA==">Learn how to use JSON Web Tokens</a>, by dwyl</li></ul>]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/java/">java</category>
      
      
      <category domain="https://b.122345.xyz/tags/java/">java</category>
      
      <category domain="https://b.122345.xyz/tags/web%E5%89%8D%E7%AB%AF/">web前端</category>
      
      <category domain="https://b.122345.xyz/tags/JWT/">JWT</category>
      
      <category domain="https://b.122345.xyz/tags/token/">token</category>
      
      <category domain="https://b.122345.xyz/tags/spring/">spring</category>
      
      
      <comments>https://b.122345.xyz/2022/07/15/JSON-Web-Token-%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>curl 的用法指南</title>
      <link>https://b.122345.xyz/2022/07/09/curl-%E7%9A%84%E7%94%A8%E6%B3%95%E6%8C%87%E5%8D%97/</link>
      <guid>https://b.122345.xyz/2022/07/09/curl-%E7%9A%84%E7%94%A8%E6%B3%95%E6%8C%87%E5%8D%97/</guid>
      <pubDate>Sat, 09 Jul 2022 11:33:03 GMT</pubDate>
      
        
        
      <description>&lt;h2 id=&quot;简介&quot;&gt;&lt;a href=&quot;#简介&quot; class=&quot;headerlink&quot; title=&quot;简介&quot;&gt;&lt;/a&gt;简介&lt;/h2&gt;&lt;p&gt;curl 是常用的命令行工具，用来请求 Web 服务器。它的名字就是客户端（client）的 URL 工具的意思。&lt;/p&gt;
&lt;p&gt;它的功能非</description>
        
      
      
      
      <content:encoded><![CDATA[<h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><p>curl 是常用的命令行工具，用来请求 Web 服务器。它的名字就是客户端（client）的 URL 工具的意思。</p><p>它的功能非常强大，命令行参数多达几十种。如果熟练的话，完全可以取代 Postman 这一类的图形界面工具。</p><img src="/2022/07/09/curl-%E7%9A%84%E7%94%A8%E6%B3%95%E6%8C%87%E5%8D%97/daefc73cd48be3d68c735bc9e54a970e.jpg" class="" title="图片[1]-curl 的用法指南-TOY论坛"><p>本文介绍它的主要命令行参数，作为日常的参考，方便查阅。内容主要翻译自<a href="https://blog.122345.xyz/?golink=aHR0cHM6Ly9jYXRvbm1hdC5uZXQvY29va2Jvb2tzL2N1cmw=">《curl cookbook》</a>。为了节约篇幅，下面的例子不包括运行时的输出，初学者可以先看我以前写的<a href="https://blog.122345.xyz/?golink=aHR0cHM6Ly93d3cucnVhbnlpZmVuZy5jb20vYmxvZy8yMDExLzA5L2N1cmwuaHRtbA==">《curl 初学者教程》</a>。</p><p>不带有任何参数时，curl 就是发出 GET 请求。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl https://www.example.com</span><br></pre></td></tr></table></figure><p>上面命令向<code>www.example.com</code>发出 GET 请求，服务器返回的内容会在命令行输出。</p><h2 id="A"><a href="#A" class="headerlink" title="-A"></a>-A</h2><p><code>-A</code>参数指定客户端的用户代理标头，即<code>User-Agent</code>。curl 的默认用户代理字符串是<code>curl/[version]</code>。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -A <span class="string">&#x27;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36&#x27;</span> https://google.com</span><br></pre></td></tr></table></figure><p>上面命令将<code>User-Agent</code>改成 Chrome 浏览器。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -A <span class="string">&#x27;&#x27;</span> https://google.com</span><br></pre></td></tr></table></figure><p>上面命令会移除<code>User-Agent</code>标头。</p><p>也可以通过<code>-H</code>参数直接指定标头，更改<code>User-Agent</code>。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -H <span class="string">&#x27;User-Agent: php/1.0&#x27;</span> https://google.com</span><br></pre></td></tr></table></figure><h2 id="b"><a href="#b" class="headerlink" title="-b"></a>-b</h2><p><code>-b</code>参数用来向服务器发送 Cookie。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -b <span class="string">&#x27;foo=bar&#x27;</span> https://google.com</span><br></pre></td></tr></table></figure><p>上面命令会生成一个标头<code>Cookie: foo=bar</code>，向服务器发送一个名为<code>foo</code>、值为<code>bar</code>的 Cookie。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -b <span class="string">&#x27;foo1=bar;foo2=bar2&#x27;</span> https://google.com</span><br></pre></td></tr></table></figure><p>上面命令发送两个 Cookie。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -b cookies.txt https://www.google.com</span><br></pre></td></tr></table></figure><p>上面命令读取本地文件<code>cookies.txt</code>，里面是服务器设置的 Cookie（参见<code>-c</code>参数），将其发送到服务器。</p><h2 id="c"><a href="#c" class="headerlink" title="-c"></a>-c</h2><p><code>-c</code>参数将服务器设置的 Cookie 写入一个文件。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -c cookies.txt https://www.google.com</span><br></pre></td></tr></table></figure><p>上面命令将服务器的 HTTP 回应所设置 Cookie 写入文本文件<code>cookies.txt</code>。</p><h2 id="d"><a href="#d" class="headerlink" title="-d"></a><strong>-d</strong></h2><p><code>-d</code>参数用于发送 POST 请求的数据体。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ curl -d<span class="string">&#x27;login=emma＆password=123&#x27;</span>-X POST https://google.com/login</span><br><span class="line"><span class="comment"># 或者</span></span><br><span class="line">$ curl -d <span class="string">&#x27;login=emma&#x27;</span> -d <span class="string">&#x27;password=123&#x27;</span> -X POST  https://google.com/login</span><br></pre></td></tr></table></figure><p>使用<code>-d</code>参数以后，HTTP 请求会自动加上标头<code>Content-Type : application/x-www-form-urlencoded</code>。并且会自动将请求转为 POST 方法，因此可以省略<code>-X POST</code>。</p><p><code>-d</code>参数可以读取本地文本文件的数据，向服务器发送。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -d <span class="string">&#x27;@data.txt&#x27;</span> https://google.com/login</span><br></pre></td></tr></table></figure><p>上面命令读取<code>data.txt</code>文件的内容，作为数据体向服务器发送。</p><h2 id="–data-urlencode"><a href="#–data-urlencode" class="headerlink" title="–data-urlencode"></a><strong>–data-urlencode</strong></h2><p><code>--data-urlencode</code>参数等同于<code>-d</code>，发送 POST 请求的数据体，区别在于会自动将发送的数据进行 URL 编码。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl --data-urlencode <span class="string">&#x27;comment=hello world&#x27;</span> https://google.com/login</span><br></pre></td></tr></table></figure><p>上面代码中，发送的数据<code>hello world</code>之间有一个空格，需要进行 URL 编码。</p><h2 id="e"><a href="#e" class="headerlink" title="-e"></a><strong>-e</strong></h2><p><code>-e</code>参数用来设置 HTTP 的标头<code>Referer</code>，表示请求的来源。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -e <span class="string">&#x27;https://google.com?q=example&#x27;</span> https://www.example.com</span><br></pre></td></tr></table></figure><p>上面命令将<code>Referer</code>标头设为<code>https://google.com?q=example</code>。</p><p><code>-H</code>参数可以通过直接添加标头<code>Referer</code>，达到同样效果。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -H <span class="string">&#x27;Referer: https://google.com?q=example&#x27;</span> https://www.example.com</span><br></pre></td></tr></table></figure><h2 id="F"><a href="#F" class="headerlink" title="-F"></a><strong>-F</strong></h2><p><code>-F</code>参数用来向服务器上传二进制文件。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -F <span class="string">&#x27;file=@photo.png&#x27;</span> https://google.com/profile</span><br></pre></td></tr></table></figure><p>上面命令会给 HTTP 请求加上标头<code>Content-Type: multipart/form-data</code>，然后将文件<code>photo.png</code>作为<code>file</code>字段上传。</p><p><code>-F</code>参数可以指定 MIME 类型。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -F <span class="string">&#x27;file=@photo.png;type=image/png&#x27;</span> https://google.com/profile</span><br></pre></td></tr></table></figure><p>上面命令指定 MIME 类型为<code>image/png</code>，否则 curl 会把 MIME 类型设为<code>application/octet-stream</code>。</p><p><code>-F</code>参数也可以指定文件名。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -F <span class="string">&#x27;file=@photo.png;filename=me.png&#x27;</span> https://google.com/profile</span><br></pre></td></tr></table></figure><p>上面命令中，原始文件名为<code>photo.png</code>，但是服务器接收到的文件名为<code>me.png</code>。</p><h2 id="G"><a href="#G" class="headerlink" title="-G"></a><strong>-G</strong></h2><p><code>-G</code>参数用来构造 URL 的查询字符串。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -G -d <span class="string">&#x27;q=kitties&#x27;</span> -d <span class="string">&#x27;count=20&#x27;</span> https://google.com/search</span><br></pre></td></tr></table></figure><p>上面命令会发出一个 GET 请求，实际请求的 URL 为<code>https://google.com/search?q=kitties&amp;count=20</code>。如果省略<code>--G</code>，会发出一个 POST 请求。</p><p>如果数据需要 URL 编码，可以结合<code>--data--urlencode</code>参数。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -G --data-urlencode <span class="string">&#x27;comment=hello world&#x27;</span> https://www.example.com</span><br></pre></td></tr></table></figure><h2 id="H"><a href="#H" class="headerlink" title="-H"></a><strong>-H</strong></h2><p><code>-H</code>参数添加 HTTP 请求的标头。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -H <span class="string">&#x27;Accept-Language: en-US&#x27;</span> https://google.com</span><br></pre></td></tr></table></figure><p>上面命令添加 HTTP 标头<code>Accept-Language: en-US</code>。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -H <span class="string">&#x27;Accept-Language: en-US&#x27;</span> -H <span class="string">&#x27;Secret-Message: xyzzy&#x27;</span> https://google.com</span><br></pre></td></tr></table></figure><p>上面命令添加两个 HTTP 标头。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -d <span class="string">&#x27;&#123;&quot;login&quot;: &quot;emma&quot;, &quot;pass&quot;: &quot;123&quot;&#125;&#x27;</span> -H <span class="string">&#x27;Content-Type: application/json&#x27;</span> https://google.com/login</span><br></pre></td></tr></table></figure><p>上面命令添加 HTTP 请求的标头是<code>Content-Type: application/json</code>，然后用<code>-d</code>参数发送 JSON 数据。</p><h2 id="i"><a href="#i" class="headerlink" title="-i"></a><strong>-i</strong></h2><p><code>-i</code>参数打印出服务器回应的 HTTP 标头。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -i https://www.example.com</span><br></pre></td></tr></table></figure><p>上面命令收到服务器回应后，先输出服务器回应的标头，然后空一行，再输出网页的源码。</p><h2 id="I"><a href="#I" class="headerlink" title="-I"></a><strong>-I</strong></h2><p><code>-I</code>参数向服务器发出 HEAD 请求，然会将服务器返回的 HTTP 标头打印出来。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -I https://www.example.com</span><br></pre></td></tr></table></figure><p>上面命令输出服务器对 HEAD 请求的回应。</p><p><code>--head</code>参数等同于<code>-I</code>。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl --<span class="built_in">head</span> https://www.example.com</span><br></pre></td></tr></table></figure><h2 id="k"><a href="#k" class="headerlink" title="-k"></a><strong>-k</strong></h2><p><code>-k</code>参数指定跳过 SSL 检测。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -k https://www.example.com</span><br></pre></td></tr></table></figure><p>上面命令不会检查服务器的 SSL 证书是否正确。</p><h2 id="L"><a href="#L" class="headerlink" title="-L"></a><strong>-L</strong></h2><p><code>-L</code>参数会让 HTTP 请求跟随服务器的重定向。curl 默认不跟随重定向。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -L -d <span class="string">&#x27;tweet=hi&#x27;</span> https://api.twitter.com/tweet</span><br></pre></td></tr></table></figure><h2 id="–limit-rate"><a href="#–limit-rate" class="headerlink" title="–limit-rate"></a><strong>–limit-rate</strong></h2><p><code>--limit-rate</code>用来限制 HTTP 请求和回应的带宽，模拟慢网速的环境。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl --limit-rate 200k https://google.com</span><br></pre></td></tr></table></figure><p>上面命令将带宽限制在每秒 200K 字节。</p><h2 id="o"><a href="#o" class="headerlink" title="-o"></a><strong>-o</strong></h2><p><code>-o</code>参数将服务器的回应保存成文件，等同于<code>wget</code>命令。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -o example.html https://www.example.com</span><br></pre></td></tr></table></figure><p>上面命令将<code>www.example.com</code>保存成<code>example.html</code>。</p><h2 id="O"><a href="#O" class="headerlink" title="-O"></a><strong>-O</strong></h2><p><code>-O</code>参数将服务器回应保存成文件，并将 URL 的最后部分当作文件名。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -O https://www.example.com/foo/bar.html</span><br></pre></td></tr></table></figure><p>上面命令将服务器回应保存成文件，文件名为<code>bar.html</code>。</p><h2 id="s"><a href="#s" class="headerlink" title="-s"></a><strong>-s</strong></h2><p><code>-s</code>参数将不输出错误和进度信息。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -s https://www.example.com</span><br></pre></td></tr></table></figure><p>上面命令一旦发生错误，不会显示错误信息。不发生错误的话，会正常显示运行结果。</p><p>如果想让 curl 不产生任何输出，可以使用下面的命令。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -s -o /dev/null https://google.com</span><br></pre></td></tr></table></figure><h2 id="S"><a href="#S" class="headerlink" title="-S"></a><strong>-S</strong></h2><p><code>-S</code>参数指定只输出错误信息，通常与<code>-s</code>一起使用。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -s -o /dev/null https://google.com</span><br></pre></td></tr></table></figure><p>上面命令没有任何输出，除非发生错误。</p><h2 id="u"><a href="#u" class="headerlink" title="-u"></a><strong>-u</strong></h2><p><code>-u</code>参数用来设置服务器认证的用户名和密码。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -u <span class="string">&#x27;bob:12345&#x27;</span> https://google.com/login</span><br></pre></td></tr></table></figure><p>上面命令设置用户名为<code>bob</code>，密码为<code>12345</code>，然后将其转为 HTTP 标头<code>Authorization: Basic Ym9iOjEyMzQ1</code>。</p><p>curl 能够识别 URL 里面的用户名和密码。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl https://bob:12345@google.com/login</span><br></pre></td></tr></table></figure><p>上面命令能够识别 URL 里面的用户名和密码，将其转为上个例子里面的 HTTP 标头。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -u <span class="string">&#x27;bob&#x27;</span> https://google.com/login</span><br></pre></td></tr></table></figure><p>上面命令只设置了用户名，执行后，curl 会提示用户输入密码。</p><h2 id="v"><a href="#v" class="headerlink" title="-v"></a><strong>-v</strong></h2><p><code>-v</code>参数输出通信的整个过程，用于调试。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -v https://www.example.com</span><br></pre></td></tr></table></figure><p><code>--trace</code>参数也可以用于调试，还会输出原始的二进制数据。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl --trace - https://www.example.com</span><br></pre></td></tr></table></figure><h2 id="x"><a href="#x" class="headerlink" title="-x"></a><strong>-x</strong></h2><p><code>-x</code>参数指定 HTTP 请求的代理。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -x socks5://james:cats@myproxy.com:8080 https://www.example.com</span><br></pre></td></tr></table></figure><p>上面命令指定 HTTP 请求通过<code>myproxy.com:8080</code>的 socks5 代理发出。</p><p>如果没有指定代理协议，默认为 HTTP。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -x james:cats@myproxy.com:8080 https://www.example.com</span><br></pre></td></tr></table></figure><p>上面命令中，请求的代理使用 HTTP 协议。</p><h2 id="X"><a href="#X" class="headerlink" title="-X"></a><strong>-X</strong></h2><p><code>-X</code>参数指定 HTTP 请求的方法。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -X POST https://www.example.com</span><br></pre></td></tr></table></figure><p>上面命令对<code>https://www.example.com</code>发出 POST 请求。</p><h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><p><a href="https://blog.122345.xyz/?golink=aHR0cHM6Ly9jYXRvbm1hdC5uZXQvY29va2Jvb2tzL2N1cmw=">Curl Cookbook</a></p>]]></content:encoded>
      
      
      <category domain="https://b.122345.xyz/categories/linux/">linux</category>
      
      
      <category domain="https://b.122345.xyz/tags/linux/">linux</category>
      
      <category domain="https://b.122345.xyz/tags/curl/">curl</category>
      
      <category domain="https://b.122345.xyz/tags/%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/">常用命令</category>
      
      
      <comments>https://b.122345.xyz/2022/07/09/curl-%E7%9A%84%E7%94%A8%E6%B3%95%E6%8C%87%E5%8D%97/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>广西移动光猫管理员超级密码收集</title>
      <link>https://b.122345.xyz/2022/07/09/%E5%B9%BF%E8%A5%BF%E7%A7%BB%E5%8A%A8%E5%85%89%E7%8C%AB%E7%AE%A1%E7%90%86%E5%91%98%E8%B6%85%E7%BA%A7%E5%AF%86%E7%A0%81%E6%94%B6%E9%9B%86/</link>
      <guid>https://b.122345.xyz/2022/07/09/%E5%B9%BF%E8%A5%BF%E7%A7%BB%E5%8A%A8%E5%85%89%E7%8C%AB%E7%AE%A1%E7%90%86%E5%91%98%E8%B6%85%E7%BA%A7%E5%AF%86%E7%A0%81%E6%94%B6%E9%9B%86/</guid>
      <pubDate>Sat, 09 Jul 2022 11:24:05 GMT</pubDate>
      
        
        
      <description>&lt;p&gt;账号: telecomadmin (华为老款8321)&lt;br&gt;密码: admintelecom&lt;/p&gt;
&lt;p&gt;账号: CMCCAdmin(烽火)&lt;br&gt;密码: aDm8H%MdA&lt;/p&gt;
&lt;p&gt;账号：admin (中兴F623)&lt;br&gt;密码：Cmcc10086#&lt;/p&gt;
&lt;</description>
        
      
      
      
      <content:encoded><![CDATA[<p>账号: telecomadmin (华为老款8321)<br>密码: admintelecom</p><p>账号: CMCCAdmin(烽火)<br>密码: aDm8H%MdA</p><p>账号：admin (中兴F623)<br>密码：Cmcc10086#</p><p>账号：CMCCAdmin (新猫统一)<br>密码：Cmcc10086#</p>]]></content:encoded>
      
      
      
      <category domain="https://b.122345.xyz/tags/%E8%B7%AF%E7%94%B1%E5%99%A8/">路由器</category>
      
      <category domain="https://b.122345.xyz/tags/%E5%85%89%E7%8C%AB/">光猫</category>
      
      
      <comments>https://b.122345.xyz/2022/07/09/%E5%B9%BF%E8%A5%BF%E7%A7%BB%E5%8A%A8%E5%85%89%E7%8C%AB%E7%AE%A1%E7%90%86%E5%91%98%E8%B6%85%E7%BA%A7%E5%AF%86%E7%A0%81%E6%94%B6%E9%9B%86/#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>IDEA 方法设置快速注释【便捷】</title>
      <link>https://b.122345.xyz/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/</link>
      <guid>https://b.122345.xyz/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/</guid>
      <pubDate>Thu, 14 Apr 2022 11:26:16 GMT</pubDate>
      
        
        
      <description>&lt;h2 id=&quot;一、方法注释&quot;&gt;&lt;a href=&quot;#一、方法注释&quot; class=&quot;headerlink&quot; title=&quot;一、方法注释&quot;&gt;&lt;/a&gt;一、方法注释&lt;/h2&gt;&lt;h3 id=&quot;1-File—-Settings-进入设置界面&quot;&gt;&lt;a href=&quot;#1-File—-Settin</description>
        
      
      
      
      <content:encoded><![CDATA[<h2 id="一、方法注释"><a href="#一、方法注释" class="headerlink" title="一、方法注释"></a>一、方法注释</h2><h3 id="1-File—-Settings-进入设置界面"><a href="#1-File—-Settings-进入设置界面" class="headerlink" title="1.File—&gt;Settings 进入设置界面"></a>1.File—&gt;Settings 进入设置界面</h3><img src="/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/d7870b14b5d60fce84994d1358774699.png" class="" title="图片[1]-IDEA 方法设置快速注释【便捷】-TOY论坛">File—>Settings<h3 id="2-找到Editor—-Live-Templates"><a href="#2-找到Editor—-Live-Templates" class="headerlink" title="2.找到Editor—&gt;Live Templates"></a>2.找到Editor—&gt;Live Templates</h3><img src="/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/3a9bce83dc5750fee02cd7a8e852b6c2.png" class="" title="图片[2]-IDEA 方法设置快速注释【便捷】-TOY论坛">Editor—>Live Templates<h3 id="3-新增一个模板"><a href="#3-新增一个模板" class="headerlink" title="3.新增一个模板"></a>3.新增一个模板</h3><p>点击右侧的 +号，选择Template Group..</p><img src="/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/5189c371870f24cbcfd4b2bbd91b3f52-1024x642.png" class="" title="图片[3]-IDEA 方法设置快速注释【便捷】-TOY论坛">New Template Group<p>输入自己想要的名称，这是我输入的</p><img src="/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/119629c0f03c003b4682d1e995381aec.png" class="" title="图片[4]-IDEA 方法设置快速注释【便捷】-TOY论坛"><p>Template Group Name</p><h3 id="4-添加内容"><a href="#4-添加内容" class="headerlink" title="4.添加内容"></a>4.添加内容</h3><p>选中后，点击+号，选择Live Template</p><img src="/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/54f8c82d58485c1cc50a9a8098238419-1024x655.png" class="" title="图片[5]-IDEA 方法设置快速注释【便捷】-TOY论坛">Add Live Template<img src="/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/406681f559d0508b9050ad61f778613b.png" class="" title="图片[6]-IDEA 方法设置快速注释【便捷】-TOY论坛">Edit Live Template<h3 id="5-设置模板内容（注释内容）"><a href="#5-设置模板内容（注释内容）" class="headerlink" title="5.设置模板内容（注释内容）"></a>5.设置模板内容（注释内容）</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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//注意是*开头，不是/**开头.  方法注释模板中的参数是 $ $, 而类中的是$&#123; &#125;. </span></span><br><span class="line">*</span><br><span class="line"> * <span class="meta">@description</span>: $description$</span><br><span class="line"> * <span class="meta">@Date</span>: $DATE$ $TIME$</span><br><span class="line"> * <span class="meta">@Param</span>: $param$</span><br><span class="line"> * <span class="meta">@Return</span>: $<span class="keyword">return</span>$</span><br><span class="line">*/</span><br></pre></td></tr></table></figure><p>选择 Edit variables 编辑每一项的参数</p><img src="/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/d5f4278eae9feec16a375436f95f740d.png" class="" title="图片[7]-IDEA 方法设置快速注释【便捷】-TOY论坛">set parameter<p>选择适用的代码类型</p><img src="/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/1966972cf4d2fcf1d32ebb92f56e70d0.png" class="" title="图片[8]-IDEA 方法设置快速注释【便捷】-TOY论坛">set language type<p>点击Ok就可以了</p><h3 id="6-效果"><a href="#6-效果" class="headerlink" title="6.效果"></a>6.效果</h3><img src="/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/da1cd14568a009ac44f05cac6580836e.png" class="" title="图片[9]-IDEA 方法设置快速注释【便捷】-TOY论坛"><h2 id="二-快捷生成类注释"><a href="#二-快捷生成类注释" class="headerlink" title="二. 快捷生成类注释"></a>二. 快捷生成类注释</h2><h3 id="1-File—-Settings-进入设置界面-1"><a href="#1-File—-Settings-进入设置界面-1" class="headerlink" title="1.File—&gt;Settings 进入设置界面"></a>1.File—&gt;Settings 进入设置界面</h3><img src="/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/d7870b14b5d60fce84994d1358774699.png" class="" title="图片[1]-IDEA 方法设置快速注释【便捷】-TOY论坛">open settings<h3 id="2-找到Editor—-Live-Templates-1"><a href="#2-找到Editor—-Live-Templates-1" class="headerlink" title="2.找到Editor—&gt;Live Templates"></a>2.找到Editor—&gt;Live Templates</h3><img src="/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/bedfede3012785340193f95e6362b543.png" class="" title="图片[11]-IDEA 方法设置快速注释【便捷】-TOY论坛">Open Feile and Code Templates<p>想设置Class就选Class，Interface便设置Interface。新建类即可生效</p><p>下面这是我的模板，可自行设计。参数详情开百度吧</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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">*<span class="doctag">@program</span>: $&#123;PROJECT_NAME&#125;</span></span><br><span class="line"><span class="comment">*<span class="doctag">@ClassName</span>: $&#123;NAME&#125;</span></span><br><span class="line"><span class="comment">*<span class="doctag">@description</span>: $&#123;description&#125;</span></span><br><span class="line"><span class="comment">*<span class="doctag">@author</span>: toy</span></span><br><span class="line"><span class="comment">*<span class="doctag">@create</span>: $&#123;YEAR&#125;-$&#123;MONTH&#125;-$&#123;DAY&#125; $&#123;HOUR&#125;:$&#123;MINUTE&#125;</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure><h3 id="3-效果"><a href="#3-效果" class="headerlink" title="3.效果"></a>3.效果</h3><img src="/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/21a807240e3a3af60dbd8c8c254106d1.png" class="" title="图片[12]-IDEA 方法设置快速注释【便捷】-TOY论坛">]]></content:encoded>
      
      
      
      <category domain="https://b.122345.xyz/tags/IDEA/">IDEA</category>
      
      <category domain="https://b.122345.xyz/tags/IDEA%E8%AE%BE%E7%BD%AE/">IDEA设置</category>
      
      
      <comments>https://b.122345.xyz/2022/04/14/IDEA-%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E5%BF%AB%E9%80%9F%E6%B3%A8%E9%87%8A%E3%80%90%E4%BE%BF%E6%8D%B7%E3%80%91/#disqus_thread</comments>
      
    </item>
    
  </channel>
</rss>
