<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ffff65535</title><link>https://blog.ffff65535.com/</link><description>Recent content on ffff65535</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sat, 22 Aug 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://blog.ffff65535.com/index.xml" rel="self" type="application/rss+xml"/><item><title>DeepSeek V4 涨价后，性价比执行模型的新选择：Muse Spark 1.2 Contributor</title><link>https://blog.ffff65535.com/posts/2026/08/22/deepseek-v4-price-increase-muse-spark-alternative/</link><pubDate>Sat, 22 Aug 2026 00:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2026/08/22/deepseek-v4-price-increase-muse-spark-alternative/</guid><description>&lt;p>DeepSeek V4 Flash 曾经是 OpenCode Go 中使用频率很高的执行模型：价格便宜、额度充足，处理代码检索、文件修改和工具调用时，基本不用担心消耗。&lt;/p>
&lt;p>但 DeepSeek V4 涨价后，情况发生了变化。DeepSeek V4 Flash 的月度额度从最初的 &lt;strong>$120&lt;/strong> 一度降到 &lt;strong>$15&lt;/strong>，后续虽调整到 &lt;strong>$30&lt;/strong>，请求价格却也同步上涨，并开始区分峰谷时段。以前连续使用一天通常只消耗 $1～$2，月度额度几乎看不到明显变化；现在稍微多用一会儿，余额就会快速下降。&lt;/p></description></item><item><title>自建 GitHub 加速服务：从 CF Workers 迁移到 VPS 部署 hubproxy + Caddy</title><link>https://blog.ffff65535.com/posts/2026/05/24/self-hosted-github-proxy-hubproxy-caddy/</link><pubDate>Sun, 24 May 2026 07:20:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2026/05/24/self-hosted-github-proxy-hubproxy-caddy/</guid><description>&lt;p>之前用的 &lt;a href="https://github.com/hunshcn/gh-proxy">gh-proxy&lt;/a>，基于 Cloudflare Workers 搭建。现在换了新域名 &lt;code>1s.gs&lt;/code>，改用 &lt;a href="https://github.com/sky22333/hubproxy">hubproxy&lt;/a> 部署在自己的 VPS 上，完全自托管，不再依赖第三方服务。&lt;/p>
&lt;hr>
&lt;h2 id="架构">架构&lt;/h2>
&lt;pre tabindex="0">&lt;code>用户 → 1s.gs → Caddy (:80/:443) → hubproxy (:5000)
 ↕
 hubproxy_net Docker 网络
&lt;/code>&lt;/pre>&lt;ul>
&lt;li>Caddy 负责 HTTPS 和反代&lt;/li>
&lt;li>hubproxy 不暴露端口，仅通过 Docker 内部网络通信&lt;/li>
&lt;li>旧域名 &lt;code>github-proxy.top&lt;/code> 显示迁移提示页，3 秒后跳转到新域名&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="步骤">步骤&lt;/h2>
&lt;h3 id="1-部署-hubproxy">1. 部署 hubproxy&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>mkdir -p /opt/services/hubproxy
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>&lt;code>/opt/services/hubproxy/docker-compose.yml&lt;/code>：&lt;/strong>&lt;/p></description></item><item><title>配置 Tailscale Peer Relay</title><link>https://blog.ffff65535.com/posts/2026/01/27/tailscale-peer-relay-setup/</link><pubDate>Tue, 27 Jan 2026 00:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2026/01/27/tailscale-peer-relay-setup/</guid><description>&lt;p>在某些网络环境中（如严格 NAT 或防火墙限制），Tailscale 无法建立设备间的直连，会自动回退到使用其全球分布的 DERP 中继服务器。虽然 DERP 可靠，但可能引入较高延迟，影响大文件传输或高清视频串流等高吞吐场景。&lt;/p></description></item><item><title>在 Netcup Web Hosting 上部署 EasyImages 2.0 图床</title><link>https://blog.ffff65535.com/posts/2025/11/28/deploy-easyimages-on-netcup-webhosting/</link><pubDate>Fri, 28 Nov 2025 00:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2025/11/28/deploy-easyimages-on-netcup-webhosting/</guid><description>&lt;p>EasyImages 2.0 是一款轻量级、无数据库依赖的开源图床程序，支持多格式上传、API 调用、水印、鉴黄等功能，非常适合个人或小规模使用。本文将手把手教你如何在 &lt;strong>Netcup 的 Web Hosting&lt;/strong> 环境中部署它。&lt;/p></description></item><item><title>在 Netcup 上修改域名的 Name Servers</title><link>https://blog.ffff65535.com/posts/2025/11/28/netcup-change-nameservers/</link><pubDate>Fri, 28 Nov 2025 00:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2025/11/28/netcup-change-nameservers/</guid><description>&lt;h1 id="在-netcup-上修改域名的-name-servers">在 Netcup 上修改域名的 Name Servers&lt;/h1>
&lt;p>如果你在 &lt;a href="https://www.netcup.de/">Netcup&lt;/a> 托管了域名，并希望将 DNS 解析切换到自定义的 Name Servers（例如 Cloudflare、自建 DNS 服务器等），需要在 Netcup 的客户控制面板（CCP）中进行设置。以下是详细操作步骤：&lt;/p></description></item><item><title>Portainer Edge Agent 连接超时问题解决：自定义 Tunnel URL</title><link>https://blog.ffff65535.com/posts/2025/10/25/fix-portainer-edge-agent-connection-timeout/</link><pubDate>Sat, 25 Oct 2025 03:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2025/10/25/fix-portainer-edge-agent-connection-timeout/</guid><description>&lt;p>当你将 &lt;strong>Portainer Server&lt;/strong> 部署在 &lt;strong>反向代理（如 Caddy、Nginx 或 Traefik）之后&lt;/strong>，并尝试添加 &lt;strong>Edge Agent&lt;/strong> 时，可能会遇到如下错误：&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-log" data-lang="log">2025/10/25 16:59:33 client: Connecting to ws://portainer.yourdomain.com:8000
2025/10/25 17:00:18 client: Connection error: dial tcp [your ip]:8000: i/o timeout
2025/10/25 17:00:18 client: Give up
&lt;/code>&lt;/pre>&lt;p>该问题的根本原因在于：&lt;strong>Portainer 默认生成的 Edge 连接信息中，Tunnel 地址为 &lt;code>域名:8000&lt;/code>，但反向代理通常并未暴露 8000 端口&lt;/strong>，导致 Edge Agent 无法建立 WebSocket 隧道连接。&lt;/p></description></item><item><title>使用 Docker Compose 部署汉化版 Portainer 并通过 Caddy 反向代理（含 Basic Auth）</title><link>https://blog.ffff65535.com/posts/2025/10/25/deploy-chinese-portainer-with-caddy-and-basic-auth/</link><pubDate>Sat, 25 Oct 2025 02:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2025/10/25/deploy-chinese-portainer-with-caddy-and-basic-auth/</guid><description>&lt;p>&lt;a href="https://www.portainer.io/">Portainer&lt;/a> 是一款轻量级的 Docker 可视化管理平台。社区维护的 &lt;strong>汉化版镜像&lt;/strong>（&lt;code>6053537/portainer-ce&lt;/code>）为中文用户提供了更友好的操作界面。本文将指导你：&lt;/p></description></item><item><title>使用 Docker Compose 部署 Caddy 并配置安全增强</title><link>https://blog.ffff65535.com/posts/2025/10/25/deploy-caddy-with-docker-compose/</link><pubDate>Sat, 25 Oct 2025 01:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2025/10/25/deploy-caddy-with-docker-compose/</guid><description>&lt;p>&lt;a href="https://caddyserver.com/">Caddy&lt;/a> 是一个现代化的 Web 服务器，以自动 HTTPS（Let’s Encrypt 集成）、简洁配置和高性能著称。本文将指导你通过 &lt;strong>Docker Compose&lt;/strong> 快速部署 Caddy，并配置安全响应头、自定义网络和日志轮转。&lt;/p></description></item><item><title>Linux 一键安装 Docker（支持国内镜像加速）</title><link>https://blog.ffff65535.com/posts/2025/10/25/install-docker-with-mirror/</link><pubDate>Sat, 25 Oct 2025 00:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2025/10/25/install-docker-with-mirror/</guid><description>&lt;p>Docker 官方提供了一个便捷的 Shell 脚本，可以自动检测系统环境并安装最新稳定版的 Docker Engine、CLI、containerd 等组件。该脚本适用于大多数主流 Linux 发行版。&lt;/p></description></item><item><title>Windows hyper-v 宿主机与虚拟机使用内部虚拟交换机进行通信</title><link>https://blog.ffff65535.com/posts/2024/03/01/windows-powershell/</link><pubDate>Fri, 01 Mar 2024 12:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2024/03/01/windows-powershell/</guid><description>&lt;ol>
&lt;li>
&lt;p>以管理员身份打开 PowerShell 控制台。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>创建内部交换机。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>New-VMSwitch -SwitchName &lt;span style="color:#e6db74">&amp;#34;Internal-VMSwitch&amp;#34;&lt;/span> -SwitchType Internal
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>执行结果&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>PS C:&lt;span style="color:#ae81ff">\W&lt;/span>INDOWS&lt;span style="color:#ae81ff">\s&lt;/span>ystem32&amp;gt; New-VMSwitch -SwitchName &lt;span style="color:#e6db74">&amp;#34;Internal-VMSwitch&amp;#34;&lt;/span> -SwitchType Internal 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Name SwitchType NetAdapterInterfaceDescription
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>---- ---------- ------------------------------
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Internal-VMSwitch Internal
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>查找刚创建的虚拟交换机的接口索引。
可以通过运行 Get-NetAdapter 来查找接口索引&lt;/p></description></item><item><title>Linux使用密钥登录并禁用密码登录</title><link>https://blog.ffff65535.com/posts/2023/10/18/linux-uses-key-logins-and-disables-password-logins/</link><pubDate>Wed, 18 Oct 2023 00:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2023/10/18/linux-uses-key-logins-and-disables-password-logins/</guid><description>&lt;h5 id="生成密钥">生成密钥&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 生成rsa密钥对&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ssh-keygen -t rsa
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Generating public/private rsa key pair.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Enter file in which to save the key &lt;span style="color:#f92672">(&lt;/span>/root/.ssh/id_rsa&lt;span style="color:#f92672">)&lt;/span>: &lt;span style="color:#75715e"># 直接enter&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Enter passphrase &lt;span style="color:#f92672">(&lt;/span>empty &lt;span style="color:#66d9ef">for&lt;/span> no passphrase&lt;span style="color:#f92672">)&lt;/span>: &lt;span style="color:#75715e"># 直接enter&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Enter same passphrase again: &lt;span style="color:#75715e"># 直接enter&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Your identification has been saved in /root/.ssh/id_rsa &lt;span style="color:#75715e"># 生成的私钥&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Your public key has been saved in /root/.ssh/id_rsa.pub &lt;span style="color:#75715e"># 生成的公钥&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="安装公钥">安装公钥&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 进入公钥目录&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cd /root/.ssh/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 将公钥写入 /root/.ssh/authorized_keys文件&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cat id_rsa.pub &amp;gt;&amp;gt; authorized_keys
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="设置ssh权限防止无法登录">设置.ssh权限，防止无法登录&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>chmod &lt;span style="color:#ae81ff">600&lt;/span> authorized_keys
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>chmod &lt;span style="color:#ae81ff">700&lt;/span> ~/.ssh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="设置ssh打开密钥登录功能">设置ssh打开密钥登录功能&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>vim /etc/ssh/sshd_config
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 启用密钥验证&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PubkeyAuthentication yes
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 关闭密码登录&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PasswordAuthentication no
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 允许root用户通过ssh登录&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PermitRootLogin yes
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h1 id="重启ssh服务">重启ssh服务&lt;/h1>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>sudo systemctl restart sshd
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="如果可以使用密码登录">如果可以使用密码登录&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>cat /etc/ssh/sshd_config.d/50-cloud-init.conf
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PasswordAuthentication yes
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 将yes改为no 或者直接删除该文件(50-cloud-init.conf)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PasswordAuthentication no
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Linux调整LVM分区</title><link>https://blog.ffff65535.com/posts/2023/04/13/linux-adjusts-the-lvm-partition/</link><pubDate>Thu, 13 Apr 2023 00:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2023/04/13/linux-adjusts-the-lvm-partition/</guid><description>&lt;h1 id="lv分区调整">lv分区调整&lt;/h1>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>df -h
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>umount /home
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>e2fsck -f /dev/mapper/debian--vg-home
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>resize2fs /dev/mapper/debian--vg-home 5G
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>lvreduce -L 5G /dev/mapper/debian--vg-home
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mount /home
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>df -h
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>lvextend -L 5G /dev/mapper/debian--vg-home &lt;span style="color:#75715e">#增大至5G&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>lvextend -L +5G /dev/mapper/debian--vg-home &lt;span style="color:#75715e">#增加5G&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>lvreduce -L 5G /dev/mapper/debian--vg-home &lt;span style="color:#75715e">#减小至5G&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>lvreduce -L -5G /dev/mapper/debian--vg-home &lt;span style="color:#75715e">#减小5G&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h1 id="创建lv分区">创建lv分区&lt;/h1>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>lvcreate -L 200G VG名字 -n LV名字
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>例：lvcreate -L 200G vg -n system
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h1 id="lvm创建swap">lvm创建swap&lt;/h1>
&lt;pre tabindex="0">&lt;code class="language-agsl" data-lang="agsl">
# 创建lv [-C y]参数 该参数用来指定逻辑卷的空间分配是连续的
lvcreate -C y -L 4G debian-vg -n swap_1
# 格式化
root@debian:~# mkswap /dev/debian-vg/swap_1 

# vim /etc/fstab 添加
/dev/mapper/debian--vg-swap_1 swap swap sw 0 0 
 swapon -va
&lt;/code>&lt;/pre></description></item><item><title>Ubuntu使用git无法读取远程仓库</title><link>https://blog.ffff65535.com/posts/2023/01/24/ubuntu-git-pull-fatal-could-not-read-from-remote-repository/</link><pubDate>Tue, 24 Jan 2023 00:28:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2023/01/24/ubuntu-git-pull-fatal-could-not-read-from-remote-repository/</guid><description>&lt;p>使用git pull时提示&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>kex_exchange_identification: Connection closed by remote host
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Connection closed by 20.205.243.166 port &lt;span style="color:#ae81ff">22&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>fatal: 无法读取远程仓库。 请确认您有正确的访问权限并且仓库存在。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>或
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>fatal: Could not read from remote repository.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>可能是使用了网络代理导致的，可以使用443端口进行ssh连接
可参考一下链接进行处理
&lt;a href="https://docs.github.com/en/authentication/troubleshooting-ssh/using-ssh-over-the-https-port">https://docs.github.com/en/authentication/troubleshooting-ssh/using-ssh-over-the-https-port&lt;/a>&lt;/p></description></item><item><title>windows 环境运行jacob的一些报错处理</title><link>https://blog.ffff65535.com/posts/2022/11/13/windows-server-jacob-word2pdf/</link><pubDate>Sun, 13 Nov 2022 00:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/11/13/windows-server-jacob-word2pdf/</guid><description>&lt;h2 id="comjacobcomcomfailexception-variantchangetype-failed">com.jacob.com.ComFailException: VariantChangeType failed&lt;/h2>
&lt;p>报错信息如下&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>com.&lt;span style="color:#a6e22e">jacob&lt;/span>.&lt;span style="color:#a6e22e">com&lt;/span>.&lt;span style="color:#a6e22e">ComFailException&lt;/span>: VariantChangeType failed
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>解决方案：
win2008 以下 需要在
C:\Windows\System32\config\systemprofile\Desktop
建立文件夹
win2008 及以上 需要在
C:\Windows\SysWOW64\config\systemprofile\Desktop&lt;/p>
&lt;p>可以直接执行下边的powershell脚本创建&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span>&lt;span style="color:#f92672">((&lt;/span>Test-Path &lt;span style="color:#e6db74">&amp;#34;C:\Windows\System32\config\systemprofile\Desktop&amp;#34;&lt;/span>&lt;span style="color:#f92672">)&lt;/span> -ne &lt;span style="color:#e6db74">&amp;#34;True&amp;#34;&lt;/span>&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> New-Item -Path &lt;span style="color:#e6db74">&amp;#34;C:\Windows\System32\config\systemprofile\Desktop&amp;#34;&lt;/span> -ItemType Directory
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span>&lt;span style="color:#f92672">((&lt;/span>Test-Path &lt;span style="color:#e6db74">&amp;#34;C:\Windows\SysWOW64\config\systemprofile\Desktop&amp;#34;&lt;/span>&lt;span style="color:#f92672">)&lt;/span> -ne &lt;span style="color:#e6db74">&amp;#34;True&amp;#34;&lt;/span>&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> New-Item -Path &lt;span style="color:#e6db74">&amp;#34;C:\Windows\SysWOW64\config\systemprofile\Desktop&amp;#34;&lt;/span> -ItemType Directory
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="saveas-source-microsoft-powerpoint-description-presentationsaveas--powerpoint-无法将-0-保存到-1">SaveAs Source: Microsoft PowerPoint Description: Presentation.SaveAs : PowerPoint 无法将 ^0 保存到 ^1。&lt;/h2>
&lt;p>报错信息如下&lt;/p></description></item><item><title>Windows powershell</title><link>https://blog.ffff65535.com/posts/2022/11/02/windows-powershell/</link><pubDate>Wed, 02 Nov 2022 12:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/11/02/windows-powershell/</guid><description>&lt;ul>
&lt;li>判断指定文件夹是否存在，若存在则删除文件夹内所有文件与子目录&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$CONFIG_PATH&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;C:\test&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$TRUE_FALSE&lt;span style="color:#f92672">=(&lt;/span>Test-Path $CONFIG_PATH&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span>&lt;span style="color:#f92672">(&lt;/span>$TRUE_FALSE -eq &lt;span style="color:#e6db74">&amp;#34;True&amp;#34;&lt;/span>&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ls $CONFIG_PATH | Remove-Item -Recurse
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>判断指定bat文件是否存在，存在则执行该文件&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$CONFIG_PATH&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;C:\test\test.bat&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$TRUE_FALSE&lt;span style="color:#f92672">=(&lt;/span>Test-Path $CONFIG_PATH&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span>&lt;span style="color:#f92672">(&lt;/span>$TRUE_FALSE -eq &lt;span style="color:#e6db74">&amp;#34;True&amp;#34;&lt;/span>&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> start $CONFIG_PATH
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>jdk11 httpclient的基本使用</title><link>https://blog.ffff65535.com/posts/2022/10/26/jdk11-httpclient/</link><pubDate>Wed, 26 Oct 2022 15:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/10/26/jdk11-httpclient/</guid><description>&lt;p>构建请求参数&lt;strong>java.net.http.HttpRequest&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>请求 URI&lt;/li>
&lt;li>请求类型（GET、PUT、POST、DELETE）&lt;/li>
&lt;li>请求体&lt;/li>
&lt;li>超时时间&lt;/li>
&lt;li>请求请求头&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>HttpRequest request &lt;span style="color:#f92672">=&lt;/span> HttpRequest.&lt;span style="color:#a6e22e">newBuilder&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 请求url&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#a6e22e">uri&lt;/span>(URI.&lt;span style="color:#a6e22e">create&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;http://openjdk.java.net/&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 超时时间&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#a6e22e">timeout&lt;/span>(Duration.&lt;span style="color:#a6e22e">ofMinutes&lt;/span>(1))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 请求头&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#a6e22e">header&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Content-Type&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;application/json&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 请求类型GET、POST、PUT、DELETE&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#a6e22e">POST&lt;/span>(HttpRequest.&lt;span style="color:#a6e22e">BodyPublishers&lt;/span>.&lt;span style="color:#a6e22e">ofString&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;请求体&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#a6e22e">build&lt;/span>();
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="发送请求javanethttphttpclient">发送请求java.net.http.HttpClient&lt;/h3>
&lt;ul>
&lt;li>首选协议版本（ HTTP/1.1 或 HTTP/2 ）&lt;/li>
&lt;li>是否跟随重定向&lt;/li>
&lt;li>代理&lt;/li>
&lt;li>身份验证器&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>HttpClient client &lt;span style="color:#f92672">=&lt;/span> HttpClient.&lt;span style="color:#a6e22e">newBuilder&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 首选协议版本 默认情况下，客户端将使用 HTTP/2发送请求。发送到尚不支持 HTTP/2的服务器的请求将自动降级为HTTP/1.1。&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#a6e22e">version&lt;/span>(HttpClient.&lt;span style="color:#a6e22e">Version&lt;/span>.&lt;span style="color:#a6e22e">HTTP_2&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 重定向策略&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#a6e22e">followRedirects&lt;/span>(HttpClient.&lt;span style="color:#a6e22e">Redirect&lt;/span>.&lt;span style="color:#a6e22e">NORMAL&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 代理&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#a6e22e">proxy&lt;/span>(ProxySelector.&lt;span style="color:#a6e22e">of&lt;/span>(&lt;span style="color:#66d9ef">new&lt;/span> InetSocketAddress(&lt;span style="color:#e6db74">&amp;#34;www-proxy.com&amp;#34;&lt;/span>, 8080)))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 超时时间&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#a6e22e">connectTimeout&lt;/span>(Duration.&lt;span style="color:#a6e22e">ofSeconds&lt;/span>(6))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#a6e22e">build&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">try&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 发送同步请求&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> response &lt;span style="color:#f92672">=&lt;/span> client.&lt;span style="color:#a6e22e">send&lt;/span>(request, HttpResponse.&lt;span style="color:#a6e22e">BodyHandlers&lt;/span>.&lt;span style="color:#a6e22e">ofString&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 发送异步请求&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> future &lt;span style="color:#f92672">=&lt;/span> client.&lt;span style="color:#a6e22e">sendAsync&lt;/span>(request, HttpResponse.&lt;span style="color:#a6e22e">BodyHandlers&lt;/span>.&lt;span style="color:#a6e22e">ofString&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> responseAsync &lt;span style="color:#f92672">=&lt;/span> future.&lt;span style="color:#a6e22e">get&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#66d9ef">catch&lt;/span> (IOException e) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">throw&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> RuntimeException(e);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#66d9ef">catch&lt;/span> (InterruptedException e) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">throw&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> RuntimeException(e);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#66d9ef">catch&lt;/span> (ExecutionException e) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">throw&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> RuntimeException(e);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>直接使用默认设置发送请求&lt;/p></description></item><item><title>友链</title><link>https://blog.ffff65535.com/links/</link><pubDate>Sun, 18 Sep 2022 00:00:00 +0800</pubDate><guid>https://blog.ffff65535.com/links/</guid><description>&lt;p>暂无友链，欢迎联系交换友链。&lt;/p></description></item><item><title>springboot 自定义校验注解</title><link>https://blog.ffff65535.com/posts/2022/05/20/java-springboot-custom-validation/</link><pubDate>Fri, 20 May 2022 22:24:13 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/05/20/java-springboot-custom-validation/</guid><description>&lt;p>&lt;a href="./%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%A1%E9%AA%8C%E6%B3%A8%E8%A7%A3ConstraintValidator.md" title=":include">自定义校验注解ConstraintValidator&lt;/a> 不太合适,优化一下&lt;/p>
&lt;p>maven&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&amp;lt;!-- Validation --&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;dependency&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;artifactId&amp;gt;spring-boot-starter-validation&amp;lt;/artifactId&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/dependency&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>自定义校验注解&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>import javax.validation.Constraint;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import javax.validation.Payload;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import java.lang.annotation.*;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/**
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> * 枚举校验注解
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> *
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> */
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>@Target&lt;span style="color:#f92672">({&lt;/span>ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE&lt;span style="color:#f92672">})&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>@Retention&lt;span style="color:#f92672">(&lt;/span>RetentionPolicy.RUNTIME&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>@Documented
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>@Constraint&lt;span style="color:#f92672">(&lt;/span>validatedBy &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">{&lt;/span>EnumValidator.class&lt;span style="color:#f92672">})&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>public @interface EnumValid &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String message&lt;span style="color:#f92672">()&lt;/span> default &lt;span style="color:#e6db74">&amp;#34;&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Class&amp;lt;?&amp;gt;&lt;span style="color:#f92672">[]&lt;/span> groups&lt;span style="color:#f92672">()&lt;/span> default &lt;span style="color:#f92672">{}&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Class&amp;lt;? extends Payload&amp;gt;&lt;span style="color:#f92672">[]&lt;/span> payload&lt;span style="color:#f92672">()&lt;/span> default &lt;span style="color:#f92672">{}&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> /**
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> * 目标枚举类
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> */
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Class&amp;lt;?&amp;gt; target&lt;span style="color:#f92672">()&lt;/span> default Class.class;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>注解校验逻辑&lt;/p></description></item><item><title>Spring cache + Redis LocalDateTime反序列化</title><link>https://blog.ffff65535.com/posts/2022/05/20/spring-cache-redis-localdatetime-serializable/</link><pubDate>Fri, 20 May 2022 22:21:21 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/05/20/spring-cache-redis-localdatetime-serializable/</guid><description>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>/**
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>* DateTime格式化字符串
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>*/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>private static final String DEFAULT_DATETIME_PATTERN &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;yyyy-MM-dd HH:mm:ss&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/**
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>* Date格式化字符串
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>*/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>private static final String DEFAULT_DATE_PATTERN &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/**
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>* Time格式化字符串
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>*/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>private static final String DEFAULT_TIME_PATTERN &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;HH:mm:ss&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>private RedisCacheConfiguration getRedisCacheConfiguration&lt;span style="color:#f92672">()&lt;/span> &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> // 配置序列化（解决乱码的问题）
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> RedisCacheConfiguration config &lt;span style="color:#f92672">=&lt;/span> RedisCacheConfiguration.defaultCacheConfig&lt;span style="color:#f92672">()&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> //Key序列化方式redisSerializer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .serializeKeysWith&lt;span style="color:#f92672">(&lt;/span>RedisSerializationContext.SerializationPair.fromSerializer&lt;span style="color:#f92672">(&lt;/span>keySerializer&lt;span style="color:#f92672">()))&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .serializeValuesWith&lt;span style="color:#f92672">(&lt;/span>RedisSerializationContext.SerializationPair.fromSerializer&lt;span style="color:#f92672">(&lt;/span>valueSerializer&lt;span style="color:#f92672">()))&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .disableCachingNullValues&lt;span style="color:#f92672">()&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> config;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/**
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> * key 序列化
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> *
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> * @return
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> */
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>private RedisSerializer&amp;lt;String&amp;gt; keySerializer&lt;span style="color:#f92672">()&lt;/span> &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> new StringRedisSerializer&lt;span style="color:#f92672">()&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/**
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> * 值采用JSON序列化
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> *
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> * @return
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> */
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>private RedisSerializer&amp;lt;Object&amp;gt; valueSerializer&lt;span style="color:#f92672">()&lt;/span> &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Jackson2JsonRedisSerializer jackson2JsonRedisSerializer &lt;span style="color:#f92672">=&lt;/span> new Jackson2JsonRedisSerializer&lt;span style="color:#f92672">(&lt;/span>Object.class&lt;span style="color:#f92672">)&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> // 解决查询缓存转换异常的问题
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ObjectMapper om &lt;span style="color:#f92672">=&lt;/span> new ObjectMapper&lt;span style="color:#f92672">()&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> om.setVisibility&lt;span style="color:#f92672">(&lt;/span>PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY&lt;span style="color:#f92672">)&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> om.activateDefaultTyping&lt;span style="color:#f92672">(&lt;/span>new ObjectMapper&lt;span style="color:#f92672">()&lt;/span>.getPolymorphicTypeValidator&lt;span style="color:#f92672">()&lt;/span>, ObjectMapper.DefaultTyping.NON_FINAL&lt;span style="color:#f92672">)&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> jackson2JsonRedisSerializer.setObjectMapper&lt;span style="color:#f92672">(&lt;/span>om&lt;span style="color:#f92672">)&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> // Java8日期日期处理 LocalTime,LocalDate,LocalDateTime
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> JavaTimeModule javaTimeModule &lt;span style="color:#f92672">=&lt;/span> new JavaTimeModule&lt;span style="color:#f92672">()&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> javaTimeModule.addSerializer&lt;span style="color:#f92672">(&lt;/span>LocalDateTime.class, new LocalDateTimeSerializer&lt;span style="color:#f92672">(&lt;/span>DateTimeFormatter.ofPattern&lt;span style="color:#f92672">(&lt;/span>DEFAULT_DATETIME_PATTERN&lt;span style="color:#f92672">)))&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> javaTimeModule.addSerializer&lt;span style="color:#f92672">(&lt;/span>LocalDate.class, new LocalDateSerializer&lt;span style="color:#f92672">(&lt;/span>DateTimeFormatter.ofPattern&lt;span style="color:#f92672">(&lt;/span>DEFAULT_DATE_PATTERN&lt;span style="color:#f92672">)))&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> javaTimeModule.addSerializer&lt;span style="color:#f92672">(&lt;/span>LocalTime.class, new LocalTimeSerializer&lt;span style="color:#f92672">(&lt;/span>DateTimeFormatter.ofPattern&lt;span style="color:#f92672">(&lt;/span>DEFAULT_TIME_PATTERN&lt;span style="color:#f92672">)))&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> javaTimeModule.addDeserializer&lt;span style="color:#f92672">(&lt;/span>LocalDateTime.class, new LocalDateTimeDeserializer&lt;span style="color:#f92672">(&lt;/span>DateTimeFormatter.ofPattern&lt;span style="color:#f92672">(&lt;/span>DEFAULT_DATETIME_PATTERN&lt;span style="color:#f92672">)))&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> javaTimeModule.addDeserializer&lt;span style="color:#f92672">(&lt;/span>LocalDate.class, new LocalDateDeserializer&lt;span style="color:#f92672">(&lt;/span>DateTimeFormatter.ofPattern&lt;span style="color:#f92672">(&lt;/span>DEFAULT_DATE_PATTERN&lt;span style="color:#f92672">)))&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> javaTimeModule.addDeserializer&lt;span style="color:#f92672">(&lt;/span>LocalTime.class, new LocalTimeDeserializer&lt;span style="color:#f92672">(&lt;/span>DateTimeFormatter.ofPattern&lt;span style="color:#f92672">(&lt;/span>DEFAULT_TIME_PATTERN&lt;span style="color:#f92672">)))&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> om.registerModule&lt;span style="color:#f92672">(&lt;/span>javaTimeModule&lt;span style="color:#f92672">)&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> jackson2JsonRedisSerializer.setObjectMapper&lt;span style="color:#f92672">(&lt;/span>om&lt;span style="color:#f92672">)&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> jackson2JsonRedisSerializer;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Debian安装GraphicsMagick</title><link>https://blog.ffff65535.com/posts/2022/05/12/debian-install-graphicsmagick/</link><pubDate>Thu, 12 May 2022 21:49:10 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/05/12/debian-install-graphicsmagick/</guid><description>&lt;p>先安装一堆乱七八糟的库，具体是干啥的，我懒得细看，一股脑全装上去了&lt;/p>
&lt;p>可以参考这两个链接&lt;/p>
&lt;ol>
&lt;li>&lt;a href="http://www.graphicsmagick.org/README.html">http://www.graphicsmagick.org/README.html&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.graphicsmagick.org/INSTALL-unix.html">http://www.graphicsmagick.org/INSTALL-unix.html&lt;/a>&lt;/li>
&lt;/ol>
&lt;p>
&lt;figure>
 &lt;img src="./graphicsmagick-debian-packages.png" alt="GraphicsMagick debian packages" />
&lt;/figure>


&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 从数码相机读取原始图像。当使用通用 RAW 文件格式扩展名读取文件时，会自动调用 Dcraw。&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install dcraw
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install fonts-urw-base35
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 阅读 Postscript 或便携式文档格式 (PDF)。&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install ghostscript
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 读取 HP-GL 图像格式。请注意，HPGL 是一种绘图仪文件格式。HP 打印机通常接受 PCL 格式而不是 HPGL 格式。Ghostscript（见上文）也是必需的。&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install hp2xx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 这玩意安装太慢了&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install ttf-mscorefonts-installer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libbz2-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libfreetype6-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libjbig-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install liblcms2-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install liblzma-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libpng-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libtiff-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libtool
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libwebp-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libwmf-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libx11-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libxdmcp-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libxext-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libxft-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libxml2-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libxt-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libzstd-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install zlib1g-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libperl-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># heif图片支持&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libjpeg-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libheif-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apt install libde265-dev
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="安装graphicsmagick">安装GraphicsMagick&lt;/h2>
&lt;p>有两种安装方法&lt;/p></description></item><item><title>使用java终止office进程</title><link>https://blog.ffff65535.com/posts/2022/05/06/java-kill-office-process/</link><pubDate>Fri, 06 May 2022 20:08:45 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/05/06/java-kill-office-process/</guid><description>&lt;p>需要jdk大于等于1.8,否则需要重写convertStr()方法&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> lombok.extern.slf4j.Slf4j;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> java.io.BufferedReader;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> java.io.IOException;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> java.io.InputStreamReader;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> java.util.stream.Collectors;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">@Slf4j&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">KillUtils&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">final&lt;/span> String kill_wscript &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;taskkill /f /t /im wscript.exe&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">final&lt;/span> String kill_WINWORD &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;taskkill /f /t /im WINWORD.exe&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">final&lt;/span> String kill_POWERPNT &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;taskkill /f /t /im POWERPNT.exe&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">final&lt;/span> String kill_EXCEL &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;taskkill /f /t /im EXCEL.exe&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>(String&lt;span style="color:#f92672">[]&lt;/span> args) &lt;span style="color:#66d9ef">throws&lt;/span> IOException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> killOffice();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">synchronized&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">killOffice&lt;/span>() &lt;span style="color:#66d9ef">throws&lt;/span> IOException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> log.&lt;span style="color:#a6e22e">info&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;------------------------start------------------------&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Process wscript &lt;span style="color:#f92672">=&lt;/span> Runtime.&lt;span style="color:#a6e22e">getRuntime&lt;/span>().&lt;span style="color:#a6e22e">exec&lt;/span>(kill_wscript);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Process winword &lt;span style="color:#f92672">=&lt;/span> Runtime.&lt;span style="color:#a6e22e">getRuntime&lt;/span>().&lt;span style="color:#a6e22e">exec&lt;/span>(kill_WINWORD);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Process powerpnt &lt;span style="color:#f92672">=&lt;/span> Runtime.&lt;span style="color:#a6e22e">getRuntime&lt;/span>().&lt;span style="color:#a6e22e">exec&lt;/span>(kill_POWERPNT);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Process excel &lt;span style="color:#f92672">=&lt;/span> Runtime.&lt;span style="color:#a6e22e">getRuntime&lt;/span>().&lt;span style="color:#a6e22e">exec&lt;/span>(kill_EXCEL);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> convertStr(wscript, kill_wscript);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> convertStr(winword, kill_WINWORD);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> convertStr(powerpnt, kill_POWERPNT);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> convertStr(excel, kill_EXCEL);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> log.&lt;span style="color:#a6e22e">info&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;------------------------end------------------------&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">convertStr&lt;/span>(Process process, String name) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String inputMsg &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> BufferedReader(process.&lt;span style="color:#a6e22e">inputReader&lt;/span>()).&lt;span style="color:#a6e22e">lines&lt;/span>().&lt;span style="color:#a6e22e">collect&lt;/span>(Collectors.&lt;span style="color:#a6e22e">joining&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;\n&amp;#34;&lt;/span>));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> log.&lt;span style="color:#a6e22e">info&lt;/span>(name &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#e6db74">&amp;#34;--input:{}&amp;#34;&lt;/span>, inputMsg);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String errorMsg &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> BufferedReader(process.&lt;span style="color:#a6e22e">errorReader&lt;/span>()).&lt;span style="color:#a6e22e">lines&lt;/span>().&lt;span style="color:#a6e22e">collect&lt;/span>(Collectors.&lt;span style="color:#a6e22e">joining&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;\n&amp;#34;&lt;/span>));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> log.&lt;span style="color:#a6e22e">info&lt;/span>(name &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#e6db74">&amp;#34;--error:{}&amp;#34;&lt;/span>, errorMsg);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>windows使用指定版本jdk启动jar包</title><link>https://blog.ffff65535.com/posts/2022/04/20/windows-specify-jdk-startup/</link><pubDate>Wed, 20 Apr 2022 14:33:31 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/04/20/windows-specify-jdk-startup/</guid><description>&lt;p>windows server中已经配置了一个1.8版本的jdk&lt;/p>
&lt;p>现在有一个使用jdk17的jar也要运行&lt;/p>
&lt;p>CMD执行报错&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>C:&lt;span style="color:#ae81ff">\t&lt;/span>est&amp;gt;C:&lt;span style="color:#ae81ff">\P&lt;/span>rogram Files&lt;span style="color:#ae81ff">\J&lt;/span>ava&lt;span style="color:#ae81ff">\o&lt;/span>penjdk-17.0.2_windows-x64_bin&lt;span style="color:#ae81ff">\j&lt;/span>dk-17.0.2&lt;span style="color:#ae81ff">\b&lt;/span>in&lt;span style="color:#ae81ff">\j&lt;/span>ava.exe -jar test-0.0.1-SNAPSHOT.jar
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#39;C:\Program&amp;#39;&lt;/span> 不是内部或外部命令，也不是可运行的程序
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>或批处理文件。
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>原因是&lt;code>Program Files&lt;/code>中间有一个空格，给java.exe的整个路径加上双引号&lt;/p></description></item><item><title>nextcloud配置缓存</title><link>https://blog.ffff65535.com/posts/2022/03/21/nextcloud-configures-the-cache/</link><pubDate>Mon, 21 Mar 2022 23:27:22 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/21/nextcloud-configures-the-cache/</guid><description>&lt;p>/config/config.php&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&amp;#39;memcache.local&amp;#39; =&amp;gt; &amp;#39;\OC\Memcache\APCu&amp;#39;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;#39;memcache.locking&amp;#39; =&amp;gt; &amp;#39;\OC\Memcache\Redis&amp;#39;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;#39;redis&amp;#39; =&amp;gt; [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#39;host&amp;#39; =&amp;gt; &amp;#39;127.0.0.1&amp;#39;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#39;port&amp;#39; =&amp;gt; 6379,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>],
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>参考文档&lt;/p>
&lt;blockquote>
&lt;p>&lt;a href="https://docs.nextcloud.com/server/14/admin_manual/configuration_server/caching_configuration.html">https://docs.nextcloud.com/server/14/admin_manual/configuration_server/caching_configuration.html&lt;/a>&lt;/p>&lt;/blockquote>
&lt;h3 id="小型私人家庭服务器">&lt;strong>小型/私人家庭服务器&lt;/strong>&lt;/h3>
&lt;p>仅使用 APCu：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&amp;#39;memcache.local&amp;#39; =&amp;gt; &amp;#39;\OC\Memcache\APCu&amp;#39; ,
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="小型组织单服务器设置">&lt;strong>小型组织，单服务器设置&lt;/strong>&lt;/h3>
&lt;p>使用 APCu 进行本地缓存，使用 Redis 进行文件锁定：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&amp;#39;memcache.local&amp;#39; =&amp;gt; &amp;#39;\OC\Memcache\APCu&amp;#39;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;#39;memcache.locking&amp;#39; =&amp;gt; &amp;#39;\OC\Memcache\Redis&amp;#39;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;#39;redis&amp;#39; =&amp;gt; array(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&amp;#39;host&amp;#39; =&amp;gt; &amp;#39;localhost&amp;#39;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&amp;#39;port&amp;#39; =&amp;gt; 6379,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>),
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="大型组织集群设置">&lt;strong>大型组织，集群设置&lt;/strong>&lt;/h3>
&lt;p>对除本地 memcache 之外的所有内容使用 Redis：&lt;/p></description></item><item><title>线程池</title><link>https://blog.ffff65535.com/posts/2022/03/21/java-thread-pool/</link><pubDate>Mon, 21 Mar 2022 22:26:29 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/21/java-thread-pool/</guid><description>&lt;p>参考资料：&lt;/p>
&lt;blockquote>
&lt;p>&lt;a href="https://www.bilibili.com/video/BV1V4411p7EF?p=27">https://www.bilibili.com/video/BV1V4411p7EF?p=27&lt;/a>&lt;/p>&lt;/blockquote>
&lt;blockquote>
&lt;p>&lt;a href="https://blog.csdn.net/lxy13263050001/article/details/122723983">https://blog.csdn.net/lxy13263050001/article/details/122723983&lt;/a>&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;ul>
&lt;li>背景：经常创建和销毁、使用量特别大的资源，比如并发情况下的线程，对性能影响很大&lt;/li>
&lt;li>思路：提前创建了好多个线程，放入线程池中，使用时直接获取，使用完放回池中。可以避免频繁创建销毁、实现重复利用。类似生活中的公共交通工具&lt;/li>
&lt;li>好处：
&lt;ul>
&lt;li>提高响应速度（减少了创建新线程的时间）&lt;/li>
&lt;li>降低资源消耗（重复利用线程池中线程，不需要每次都创建）&lt;/li>
&lt;li>便于线程管理
&lt;ul>
&lt;li>corePoolSize：核心池的大小&lt;/li>
&lt;li>maximumPoolSize：最大线程数&lt;/li>
&lt;li>keepAliveTime：线程没有任务是最多保持多长时间后会终止&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> java.util.concurrent.ExecutorService;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> java.util.concurrent.Executors;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * @author
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">TestPool&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>(String&lt;span style="color:#f92672">[]&lt;/span> args) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 创建有10个线程的线程池&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ExecutorService threadPool &lt;span style="color:#f92672">=&lt;/span> Executors.&lt;span style="color:#a6e22e">newFixedThreadPool&lt;/span>(10);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> threadPool.&lt;span style="color:#a6e22e">execute&lt;/span>(&lt;span style="color:#66d9ef">new&lt;/span> TestMyThread());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> threadPool.&lt;span style="color:#a6e22e">execute&lt;/span>(&lt;span style="color:#66d9ef">new&lt;/span> TestMyThread());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> threadPool.&lt;span style="color:#a6e22e">execute&lt;/span>(&lt;span style="color:#66d9ef">new&lt;/span> TestMyThread());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> threadPool.&lt;span style="color:#a6e22e">execute&lt;/span>(&lt;span style="color:#66d9ef">new&lt;/span> TestMyThread());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 关闭线程池&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> threadPool.&lt;span style="color:#a6e22e">shutdown&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">TestMyThread&lt;/span> &lt;span style="color:#66d9ef">implements&lt;/span> Runnable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">run&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> (&lt;span style="color:#66d9ef">int&lt;/span> i &lt;span style="color:#f92672">=&lt;/span> 0; i &lt;span style="color:#f92672">&amp;lt;&lt;/span> 100; i&lt;span style="color:#f92672">++&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(Thread.&lt;span style="color:#a6e22e">currentThread&lt;/span>().&lt;span style="color:#a6e22e">getName&lt;/span>() &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#e6db74">&amp;#34;-----&amp;gt;&amp;#34;&lt;/span> &lt;span style="color:#f92672">+&lt;/span> i);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>JDK5.0起提供了线程池相关API：ExecutorService和Executors&lt;/li>
&lt;li>ExecutorService：真正的线程池接口。常见子类ThreadPoolExecutor
&lt;ul>
&lt;li>void execute(Runnable command) ：执行任务/命令，没有返回值，一般用来执行Runnable&lt;/li>
&lt;li>Future submit(Callable task)：执行任务，有返回值，一般又来执行Callable&lt;/li>
&lt;li>void shutdown() ：关闭连接池&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Executors：工具类、线程池的工厂类，用于创建并返回不同类型的线程池
&lt;ul>
&lt;li>Executors.newCachedThreadPool()：创建一个可根据需要创建新线程的线程池&lt;/li>
&lt;li>Executors.newFixedThreadPool(n); 创建一个可重用固定线程数的线程池&lt;/li>
&lt;li>Executors.newSingleThreadExecutor() ：创建一个只有一个线程的线程池&lt;/li>
&lt;li>Executors.newScheduledThreadPool(n)：创建一个线程池，它可安排在给定延迟后运行命令或者定期地执行&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul></description></item><item><title>并发协作模型(生产者/消费者模式)-->信号灯法</title><link>https://blog.ffff65535.com/posts/2022/03/21/java-produce-consumption-1/</link><pubDate>Mon, 21 Mar 2022 22:26:01 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/21/java-produce-consumption-1/</guid><description>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>方法名&lt;/th>
 &lt;th>作用&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>wait()&lt;/td>
 &lt;td>Object wait() 方法让当前线程进入等待状态。直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>wait(long timeout)&lt;/td>
 &lt;td>Object wait(long timeout) 方法让当前线程处于等待(阻塞)状态，直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法，或者超过参数 timeout 设置的超时时间。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>如果 timeout 参数为 0，则不会超时，会一直进行等待，类似于 wait() 方法。&lt;/td>
 &lt;td>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>notify()&lt;/td>
 &lt;td>Object notify() 方法用于唤醒一个在此对象监视器上等待的线程。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>如果所有的线程都在此对象上等待，那么只会选择一个线程，选择是任意性的，并在对实现做出决定时发生。&lt;/td>
 &lt;td>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>notifyAll()&lt;/td>
 &lt;td>Object notifyAll() 方法用于唤醒在该对象上等待的所有线程。优先级别高的线程有限调度。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>notifyAll() 方法跟 notify() 方法一样，区别在于 notifyAll() 方法唤醒在此对象监视器上等待的所有线程，notify() 方法是一个线程。&lt;/td>
 &lt;td>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;a href="https://www.runoob.com/java/java-object-wait.html">https://www.runoob.com/java/java-object-wait.html&lt;/a>&lt;/p></description></item><item><title>并发协作模型(生产者/消费者模式)-->管程法</title><link>https://blog.ffff65535.com/posts/2022/03/21/java-produce-consumption-2/</link><pubDate>Mon, 21 Mar 2022 22:25:31 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/21/java-produce-consumption-2/</guid><description>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>方法名&lt;/th>
 &lt;th>作用&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>wait()&lt;/td>
 &lt;td>Object wait() 方法让当前线程进入等待状态。直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>wait(long timeout)&lt;/td>
 &lt;td>Object wait(long timeout) 方法让当前线程处于等待(阻塞)状态，直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法，或者超过参数 timeout 设置的超时时间。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>如果 timeout 参数为 0，则不会超时，会一直进行等待，类似于 wait() 方法。&lt;/td>
 &lt;td>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>notify()&lt;/td>
 &lt;td>Object notify() 方法用于唤醒一个在此对象监视器上等待的线程。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>如果所有的线程都在此对象上等待，那么只会选择一个线程，选择是任意性的，并在对实现做出决定时发生。&lt;/td>
 &lt;td>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>notifyAll()&lt;/td>
 &lt;td>Object notifyAll() 方法用于唤醒在该对象上等待的所有线程。优先级别高的线程有限调度。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>notifyAll() 方法跟 notify() 方法一样，区别在于 notifyAll() 方法唤醒在此对象监视器上等待的所有线程，notify() 方法是一个线程。&lt;/td>
 &lt;td>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;a href="https://www.runoob.com/java/java-object-wait.html">https://www.runoob.com/java/java-object-wait.html&lt;/a>&lt;/p></description></item><item><title>自定义校验注解ConstraintValidator</title><link>https://blog.ffff65535.com/posts/2022/03/15/java-custom-constraint-validator/</link><pubDate>Tue, 15 Mar 2022 20:52:53 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/15/java-custom-constraint-validator/</guid><description>&lt;p>新建一个枚举类，限制请求参数中的属性值只能等于枚举中的值&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">enum&lt;/span> EnumType {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 数组中是要等于的值每增加一个要校验的类型，
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 增加一个对应枚举类
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 性别&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GENDER_TYPE(&lt;span style="color:#66d9ef">new&lt;/span> String&lt;span style="color:#f92672">[]&lt;/span>{&lt;span style="color:#e6db74">&amp;#34;0&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;1&amp;#34;&lt;/span>}),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 年级&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GRADE_TYPE(&lt;span style="color:#66d9ef">new&lt;/span> String&lt;span style="color:#f92672">[]&lt;/span>{&lt;span style="color:#e6db74">&amp;#34;1&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;2&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;3&amp;#34;&lt;/span>});
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> String&lt;span style="color:#f92672">[]&lt;/span> values;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> EnumType(String&lt;span style="color:#f92672">[]&lt;/span> values) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">this&lt;/span>.&lt;span style="color:#a6e22e">values&lt;/span> &lt;span style="color:#f92672">=&lt;/span> values;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> String&lt;span style="color:#f92672">[]&lt;/span> &lt;span style="color:#a6e22e">getValues&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> values;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>新建一个自定义注解&lt;/p></description></item><item><title>守护(daemon)线程</title><link>https://blog.ffff65535.com/posts/2022/03/14/java-daemon-thread/</link><pubDate>Mon, 14 Mar 2022 17:50:40 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/14/java-daemon-thread/</guid><description>&lt;ul>
&lt;li>线程分为用户线程和守护线程&lt;/li>
&lt;li>虚拟机必须确保用户线程执行完毕&lt;/li>
&lt;li>虚拟机不用等待守护线程执行完毕
&lt;ul>
&lt;li>如：后台记录操作日志，监控内存，垃圾回收等待&amp;hellip;&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">TestThreadDaemon&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>(String&lt;span style="color:#f92672">[]&lt;/span> args) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> God god &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> God();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Thread godThread &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> Thread(god);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 默认是false，表示用户线程&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> godThread.&lt;span style="color:#a6e22e">setDaemon&lt;/span>(&lt;span style="color:#66d9ef">true&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> godThread.&lt;span style="color:#a6e22e">start&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 你 用户线程启动&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">new&lt;/span> Thread(&lt;span style="color:#66d9ef">new&lt;/span> You()).&lt;span style="color:#a6e22e">start&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 用户线程执行完毕，守护线程也会停止&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 上帝 守护线程&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">God&lt;/span> &lt;span style="color:#66d9ef">implements&lt;/span> Runnable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">run&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">while&lt;/span> (&lt;span style="color:#66d9ef">true&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;上帝保佑着你&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 你 用户线程&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">You&lt;/span> &lt;span style="color:#66d9ef">implements&lt;/span> Runnable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">run&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;=======hello world=======&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> (&lt;span style="color:#66d9ef">int&lt;/span> i &lt;span style="color:#f92672">=&lt;/span> 0; i &lt;span style="color:#f92672">&amp;lt;&lt;/span> 35600; i&lt;span style="color:#f92672">++&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;你一生都开心活着&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;=======goodbye world=======&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>参考资料：&lt;/p></description></item><item><title>线程优先级</title><link>https://blog.ffff65535.com/posts/2022/03/14/java-thread-priority/</link><pubDate>Mon, 14 Mar 2022 17:50:06 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/14/java-thread-priority/</guid><description>&lt;ul>
&lt;li>Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程，线程调度器按照优先级决定应该调度哪个线程来执行&lt;/li>
&lt;li>线程优先级用数字表示，范围从1~10（线程的调度由CPU决定，数字越大概率越大）
&lt;ul>
&lt;li>Thread.MIN_PRIORITY = 1&lt;/li>
&lt;li>Thread.NORM_PRIORITY = 5&lt;/li>
&lt;li>Thread.MAX_PRIORITY = 10&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>使用以下方法改变或获取线程优先级
&lt;ul>
&lt;li>getPriority()&lt;/li>
&lt;li>setPriority(int xxx)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">TestThreadPriority&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>(String&lt;span style="color:#f92672">[]&lt;/span> args) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 打印主线程默认优先级&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(Thread.&lt;span style="color:#a6e22e">currentThread&lt;/span>().&lt;span style="color:#a6e22e">getName&lt;/span>() &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#e6db74">&amp;#34;====&amp;#34;&lt;/span> &lt;span style="color:#f92672">+&lt;/span> Thread.&lt;span style="color:#a6e22e">currentThread&lt;/span>().&lt;span style="color:#a6e22e">getPriority&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Priority priority &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> Priority();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Thread t1 &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> Thread(priority, &lt;span style="color:#e6db74">&amp;#34;t1&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Thread t2 &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> Thread(priority, &lt;span style="color:#e6db74">&amp;#34;t2&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Thread t3 &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> Thread(priority, &lt;span style="color:#e6db74">&amp;#34;t3&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Thread t4 &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> Thread(priority, &lt;span style="color:#e6db74">&amp;#34;t4&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Thread t5 &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> Thread(priority, &lt;span style="color:#e6db74">&amp;#34;t5&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Thread t6 &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> Thread(priority, &lt;span style="color:#e6db74">&amp;#34;t6&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> t1.&lt;span style="color:#a6e22e">start&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> t2.&lt;span style="color:#a6e22e">setPriority&lt;/span>(1);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> t2.&lt;span style="color:#a6e22e">start&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> t3.&lt;span style="color:#a6e22e">setPriority&lt;/span>(4);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> t3.&lt;span style="color:#a6e22e">start&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> t4.&lt;span style="color:#a6e22e">setPriority&lt;/span>(Thread.&lt;span style="color:#a6e22e">MAX_PRIORITY&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> t4.&lt;span style="color:#a6e22e">start&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> t5.&lt;span style="color:#a6e22e">setPriority&lt;/span>(6);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> t5.&lt;span style="color:#a6e22e">start&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> t6.&lt;span style="color:#a6e22e">setPriority&lt;/span>(8);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> t6.&lt;span style="color:#a6e22e">start&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">Priority&lt;/span> &lt;span style="color:#66d9ef">implements&lt;/span> Runnable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">run&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(Thread.&lt;span style="color:#a6e22e">currentThread&lt;/span>().&lt;span style="color:#a6e22e">getName&lt;/span>() &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#e6db74">&amp;#34;====&amp;#34;&lt;/span> &lt;span style="color:#f92672">+&lt;/span> Thread.&lt;span style="color:#a6e22e">currentThread&lt;/span>().&lt;span style="color:#a6e22e">getPriority&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>参考资料：&lt;/p></description></item><item><title>观测线程状态</title><link>https://blog.ffff65535.com/posts/2022/03/14/java-observation-thread/</link><pubDate>Mon, 14 Mar 2022 17:49:32 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/14/java-observation-thread/</guid><description>&lt;p>线程状态&lt;/p>
&lt;ul>
&lt;li>NEW&lt;/li>
&lt;li>尚未启动的线程处于此状态&lt;/li>
&lt;li>RUNNABLE&lt;/li>
&lt;li>在java虚拟机中执行的线程处于此状态&lt;/li>
&lt;li>BLOCKED&lt;/li>
&lt;li>被阻塞等待监听器锁定的线程处于此状态&lt;/li>
&lt;li>WAITING&lt;/li>
&lt;li>正在等待另一个线程执行特定动作的线程处于此状态&lt;/li>
&lt;li>TIMED_WAITING&lt;/li>
&lt;li>正在等待另一个线程执行动作到达指定等待时间的线程处于此状态&lt;/li>
&lt;li>TERMINATED&lt;/li>
&lt;li>已退出的线程处于此状态&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">enum&lt;/span> State {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> NEW,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> RUNNABLE,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> BLOCKED,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> WAITING,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> TIMED_WAITING,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> TERMINATED;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;pre tabindex="0">&lt;code>/**
 *观察测试线程的状态
*/
public class TestThreadState {
 public static void main(String[] args) {
 Thread thread = new Thread(() -&amp;gt; {
 for (int i = 0; i &amp;lt; 10; i++) {
 try {
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 System.out.println(&amp;#34;////////&amp;#34;);
 }
 }, &amp;#34;观测线程&amp;#34;);
 // 观察状态 NEW
 System.out.println(thread.getState());

 // 观察启动后
 thread.start();
 // RUNNABLE
 System.out.println(thread.getState());

 // 线程不终止一直输出状态
 while (thread.getState() != Thread.State.TERMINATED) {
 try {
 Thread.sleep(100);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 // TIMED_WAITING
 System.out.println(thread.getState());
 }
 //TERMINATED
 System.out.println(thread.getState());
 }
}
&lt;/code>&lt;/pre>&lt;p>参考资料：&lt;/p></description></item><item><title>lambda表达式</title><link>https://blog.ffff65535.com/posts/2022/03/14/java-lambda/</link><pubDate>Mon, 14 Mar 2022 17:48:51 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/14/java-lambda/</guid><description>&lt;p>&lt;em>函数式接口(Functional Interface)就是一个有且仅有一个抽象方法，但是可以有多个非抽象方法的接口。&lt;/em>&lt;/p>
&lt;p>&lt;em>函数式接口可以被隐式转换为 lambda 表达式。&lt;/em>&lt;/p></description></item><item><title>操作线程</title><link>https://blog.ffff65535.com/posts/2022/03/14/java-operation-thread/</link><pubDate>Mon, 14 Mar 2022 17:47:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/14/java-operation-thread/</guid><description>&lt;h1 id="线程停止">线程停止&lt;/h1>
&lt;ol>
&lt;li>建议线程正常停止&amp;mdash;-&amp;gt;利用此时，不建议死循环&lt;/li>
&lt;li>建议使用标志位&amp;mdash;-&amp;gt;设置一个标志位&lt;/li>
&lt;li>不要使用stop或destroy等过时或jdk不建议使用的方法&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 测试停止线程
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 1.建议线程正常停止----&amp;gt;利用此时，不建议死循环
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 2.建议使用标志位----&amp;gt;设置一个标志位
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 3.不要使用stop或destroy等过时或jdk不建议使用的方法
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">TestThredStop&lt;/span> &lt;span style="color:#66d9ef">implements&lt;/span> Runnable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 设置一个标志位&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> &lt;span style="color:#66d9ef">boolean&lt;/span> flag &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">true&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>(String&lt;span style="color:#f92672">[]&lt;/span> args) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> TestThredStop testThredStop &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> TestThredStop();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">new&lt;/span> Thread(testThredStop).&lt;span style="color:#a6e22e">start&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> (&lt;span style="color:#66d9ef">int&lt;/span> i &lt;span style="color:#f92672">=&lt;/span> 0; i &lt;span style="color:#f92672">&amp;lt;&lt;/span> 1000; i&lt;span style="color:#f92672">++&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;i=&amp;#34;&lt;/span> &lt;span style="color:#f92672">+&lt;/span> i);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (i &lt;span style="color:#f92672">==&lt;/span> 900) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 调用stop方法停止线程以转换标志位&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> testThredStop.&lt;span style="color:#a6e22e">stop&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;线程停止了&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 设置一个公开的方法用于停止线程，转换标志位
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">stop&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">this&lt;/span>.&lt;span style="color:#a6e22e">flag&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">false&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">run&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">int&lt;/span> i &lt;span style="color:#f92672">=&lt;/span> 0;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">while&lt;/span> (flag) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;run正在执行&amp;#34;&lt;/span> &lt;span style="color:#f92672">+&lt;/span> i&lt;span style="color:#f92672">++&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>参考资料：&lt;/p></description></item><item><title>线程的三种创建方式</title><link>https://blog.ffff65535.com/posts/2022/03/14/java-create-thread-runnable-callable/</link><pubDate>Mon, 14 Mar 2022 17:03:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/14/java-create-thread-runnable-callable/</guid><description>&lt;h1 id="继承thread类">继承Thread类&lt;/h1>
&lt;ol>
&lt;li>继承Thread类型&lt;/li>
&lt;li>重写run方法&lt;/li>
&lt;li>调用start开启多线程&lt;/li>
&lt;/ol>
&lt;p>&lt;em>线程的执行顺序无法控制，由CPU调度执行&lt;/em>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">TestThread&lt;/span> &lt;span style="color:#66d9ef">extends&lt;/span> Thread {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>(String&lt;span style="color:#f92672">[]&lt;/span> args) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 创建一个线程对象，调用start()方法&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> TestThread testThread &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> TestThread();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 调用start方法开启多线程(观察打印日志会发现：run方法和main方法交替执行)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> testThread.&lt;span style="color:#a6e22e">start&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 调用run方法，(观察打印日志会发现：会先执行run方法，再执行main方法)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">//testThread.run();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 主线程&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> (&lt;span style="color:#66d9ef">int&lt;/span> i &lt;span style="color:#f92672">=&lt;/span> 0; i &lt;span style="color:#f92672">&amp;lt;&lt;/span> 200; i&lt;span style="color:#f92672">++&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;main方法线程--&amp;#34;&lt;/span> &lt;span style="color:#f92672">+&lt;/span> i);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 1.继承Thread类型
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 2.重写run方法
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">run&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">super&lt;/span>.&lt;span style="color:#a6e22e">run&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// run方法线程体&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> (&lt;span style="color:#66d9ef">int&lt;/span> i &lt;span style="color:#f92672">=&lt;/span> 0; i &lt;span style="color:#f92672">&amp;lt;&lt;/span> 200; i&lt;span style="color:#f92672">++&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;run方法线程--&amp;#34;&lt;/span> &lt;span style="color:#f92672">+&lt;/span> i);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>参考资料：&lt;/p></description></item><item><title>EMQX安装</title><link>https://blog.ffff65535.com/posts/2022/03/14/emqx-install/</link><pubDate>Mon, 14 Mar 2022 16:53:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/14/emqx-install/</guid><description>&lt;ol>
&lt;li>
&lt;p>通过 &lt;strong>&lt;a href="https://www.emqx.com/en/downloads/broker?osType=Linux">emqx.io&lt;/a>&lt;/strong> 或 &lt;strong>&lt;a href="https://github.com/emqx/emqx/releases">Github&lt;/a>&lt;/strong> 下载要安装的 EMQX 版本的 zip 包。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>解压zip到自己指定的目录&lt;/p>
&lt;/li>
&lt;li>
&lt;p>打开命令提示符窗口，进入emqx解压目录&lt;/p>
&lt;/li>
&lt;li>
&lt;p>输入命令：bin\emqx start 或者bin\emqx console（会弹出Erlang），启动EMQ&lt;/p></description></item><item><title>EMQX通过webhook统计设备上下线</title><link>https://blog.ffff65535.com/posts/2022/03/14/emqx-devices-through-webhook-statistics/</link><pubDate>Mon, 14 Mar 2022 16:52:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/14/emqx-devices-through-webhook-statistics/</guid><description>&lt;p>修改emqx配置文件&lt;/p>
&lt;!-- raw HTML omitted -->
&lt;!-- raw HTML omitted -->
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>web.&lt;span style="color:#a6e22e">hook&lt;/span>.&lt;span style="color:#a6e22e">url&lt;/span> &lt;span style="color:#f92672">=&lt;/span> http:&lt;span style="color:#75715e">//127.0.0.1:8080/emqx/webhook&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 取消这两项的注释&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>web.&lt;span style="color:#a6e22e">hook&lt;/span>.&lt;span style="color:#a6e22e">rule&lt;/span>.&lt;span style="color:#a6e22e">client&lt;/span>.&lt;span style="color:#a6e22e">connected&lt;/span>.&lt;span style="color:#a6e22e">1&lt;/span> &lt;span style="color:#f92672">=&lt;/span> {&lt;span style="color:#e6db74">&amp;#34;action&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;on_client_connected&amp;#34;&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>web.&lt;span style="color:#a6e22e">hook&lt;/span>.&lt;span style="color:#a6e22e">rule&lt;/span>.&lt;span style="color:#a6e22e">client&lt;/span>.&lt;span style="color:#a6e22e">disconnected&lt;/span>.&lt;span style="color:#a6e22e">1&lt;/span> &lt;span style="color:#f92672">=&lt;/span> {&lt;span style="color:#e6db74">&amp;#34;action&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;on_client_disconnected&amp;#34;&lt;/span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>打开web管理→ 模块→emqx_web_hook 启动&lt;/p>
&lt;p>post请求接口&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> lombok.extern.slf4j.Slf4j;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> org.springframework.web.bind.annotation.PostMapping;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> org.springframework.web.bind.annotation.RequestBody;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> org.springframework.web.bind.annotation.RequestMapping;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> org.springframework.web.bind.annotation.RestController;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * emqx的webhook通知
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">@Slf4j&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">@RestController&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">@RequestMapping&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;/emqx/&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">WebHookController&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">@PostMapping&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;/webhook&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">webhook&lt;/span>(&lt;span style="color:#a6e22e">@RequestBody&lt;/span> WebHookRequestBody body) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.&lt;span style="color:#a6e22e">out&lt;/span>.&lt;span style="color:#a6e22e">println&lt;/span>(body);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> lombok.Data;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> java.io.Serializable;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">@Data&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">WebHookRequestBody&lt;/span> &lt;span style="color:#66d9ef">implements&lt;/span> Serializable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 事件名称
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * client.connected	成功接入	客户端认证完成并成功接入系统后
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * client.disconnected	连接断开	客户端连接层在准备关闭时
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> String action;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 客户端 ClientId
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> String clientid;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 客户端 Username，不存在时该值为 &amp;#34;undefined&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> String username;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 客户端源 IP 地址
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> String ipaddress;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 客户端申请的心跳保活时间
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> Integer keepalive;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 协议版本号
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> Integer proto_ver;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 时间戳(秒)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> Long connected_at;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * 错误原因
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> String reason;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>参考资料：&lt;/p></description></item><item><title>ghost+nginx无限重定向</title><link>https://blog.ffff65535.com/posts/2022/03/14/ghost-nginx-unlimited-redirection/</link><pubDate>Mon, 14 Mar 2022 16:51:58 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/14/ghost-nginx-unlimited-redirection/</guid><description>&lt;p>修改ngixn配置&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>server
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> listen 80;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		listen 443 ssl http2;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> server_name ghost.你的域名.com;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> index index.php index.html index.htm default.php default.htm default.html;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> root /www/wwwroot/ghost.你的域名.com;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #SSL-START SSL相关配置，请勿删除或修改下一行带注释的404规则
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #error_page 404/404.html;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #HTTP_TO_HTTPS_START
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> if ($server_port !~ 443){
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> rewrite ^(/.*)$ https://$host$1 permanent;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #HTTP_TO_HTTPS_END
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ssl_certificate /www/server/panel/vhost/cert/ghost.你的域名.com/fullchain.pem;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ssl_certificate_key /www/server/panel/vhost/cert/ghost.你的域名.com/privkey.pem;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ssl_prefer_server_ciphers on;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ssl_session_cache shared:SSL:10m;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ssl_session_timeout 10m;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> add_header Strict-Transport-Security &amp;#34;max-age=31536000&amp;#34;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> error_page 497 https://$host$request_uri;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #SSL-END
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #ERROR-PAGE-START 错误页配置，可以注释、删除或修改
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #error_page 404 /404.html;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #error_page 502 /502.html;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #ERROR-PAGE-END
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #PHP-INFO-START PHP引用配置，可以注释或修改
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		include enable-php-00.conf;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #PHP-INFO-END
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # 拦截请求，直接返回上传的静态图片资源，缓存时间 1 个月
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> location ^~ /content/images {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> alias /www/ghost_site/content/images;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> expires 1M;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> access_log off;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> add_header Cache-Control &amp;#34;public&amp;#34;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> location ~ ^/(image|javascript|js|css|media|static)/ {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_pass http://127.0.0.1:2368;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # root /www/ghost.qinan.co/web/static/;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> access_log off;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> expires 30d;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # 不缓存 ghost 核心文件（反向代理后台管理）
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> location ^~ /ghost/ {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_set_header X-Real-IP $remote_addr;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_set_header X-Forwarded-Proto $scheme;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_set_header Host $http_host;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_pass http://127.0.0.1:2368;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # favicon
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> location = /favicon.ico {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> root /www/ghost_site/core/shared;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> access_log off;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> log_not_found off;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> expires 30d;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # cache urls
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # 反向代理博客请求到服务端
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> location / {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_cache_valid 200 60m;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_cache_bypass $http_cache_control;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_redirect off;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> add_header X-Proxy-Cache $upstream_cache_status;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # 后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_set_header Host $host;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_set_header X-Real-IP $remote_addr;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_set_header X-Forwarded-Proto https;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_set_header X-Forwarded-Host $host;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_pass http://127.0.0.1:2368;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_max_temp_file_size 0;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_connect_timeout 90;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_send_timeout 90;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_read_timeout 90;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_buffering off;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> proxy_temp_file_write_size 64k;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> location ~ /\.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> deny all;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> include /www/server/panel/vhost/rewrite/ghost.你的域名.com.conf;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #REWRITE-END
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #禁止访问的文件或目录
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> return 404;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> #一键申请SSL证书验证目录相关设置
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> location ~ \.well-known{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> allow all;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> expires 30d;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> error_log /dev/null;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> access_log /dev/null;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> location ~ .*\.(js|css)?$
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> expires 12h;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> error_log /dev/null;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> access_log /dev/null;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		access_log /www/wwwlogs/ghost.你的域名.com.log;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> error_log /www/wwwlogs/ghost.你的域名.com.error.log;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>参考资料：&lt;/p></description></item><item><title>windows server环境documents4j转换excel报错</title><link>https://blog.ffff65535.com/posts/2022/03/14/windows-server-documents4j-word2pdf/</link><pubDate>Mon, 14 Mar 2022 16:50:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/14/windows-server-documents4j-word2pdf/</guid><description>&lt;p>错误描述：ppt和wrod可以正常转换，excel转换报错&lt;/p>
&lt;p>报错信息如下&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>com.&lt;span style="color:#a6e22e">documents4j&lt;/span>.&lt;span style="color:#a6e22e">throwables&lt;/span>.&lt;span style="color:#a6e22e">FileSystemInteractionException&lt;/span>: Could not access target file
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	at com.&lt;span style="color:#a6e22e">documents4j&lt;/span>.&lt;span style="color:#a6e22e">util&lt;/span>.&lt;span style="color:#a6e22e">Reaction$FileSystemInteractionExceptionBuilder&lt;/span>.&lt;span style="color:#a6e22e">make&lt;/span>(Reaction.&lt;span style="color:#a6e22e">java&lt;/span>:180)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	at com.&lt;span style="color:#a6e22e">documents4j&lt;/span>.&lt;span style="color:#a6e22e">util&lt;/span>.&lt;span style="color:#a6e22e">Reaction$ExceptionalReaction&lt;/span>.&lt;span style="color:#a6e22e">apply&lt;/span>(Reaction.&lt;span style="color:#a6e22e">java&lt;/span>:75)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	at com.&lt;span style="color:#a6e22e">documents4j&lt;/span>.&lt;span style="color:#a6e22e">conversion&lt;/span>.&lt;span style="color:#a6e22e">ExternalConverterScriptResult&lt;/span>.&lt;span style="color:#a6e22e">resolve&lt;/span>(ExternalConverterScriptResult.&lt;span style="color:#a6e22e">java&lt;/span>:70)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	at com.&lt;span style="color:#a6e22e">documents4j&lt;/span>.&lt;span style="color:#a6e22e">conversion&lt;/span>.&lt;span style="color:#a6e22e">ProcessFutureWrapper&lt;/span>.&lt;span style="color:#a6e22e">evaluateExitValue&lt;/span>(ProcessFutureWrapper.&lt;span style="color:#a6e22e">java&lt;/span>:50)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	at com.&lt;span style="color:#a6e22e">documents4j&lt;/span>.&lt;span style="color:#a6e22e">conversion&lt;/span>.&lt;span style="color:#a6e22e">ProcessFutureWrapper&lt;/span>.&lt;span style="color:#a6e22e">get&lt;/span>(ProcessFutureWrapper.&lt;span style="color:#a6e22e">java&lt;/span>:38)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	at com.&lt;span style="color:#a6e22e">documents4j&lt;/span>.&lt;span style="color:#a6e22e">conversion&lt;/span>.&lt;span style="color:#a6e22e">ProcessFutureWrapper&lt;/span>.&lt;span style="color:#a6e22e">get&lt;/span>(ProcessFutureWrapper.&lt;span style="color:#a6e22e">java&lt;/span>:11)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	at com.&lt;span style="color:#a6e22e">documents4j&lt;/span>.&lt;span style="color:#a6e22e">job&lt;/span>.&lt;span style="color:#a6e22e">AbstractFutureWrappingPriorityFuture&lt;/span>.&lt;span style="color:#a6e22e">run&lt;/span>(AbstractFutureWrappingPriorityFuture.&lt;span style="color:#a6e22e">java&lt;/span>:78)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	at java.&lt;span style="color:#a6e22e">util&lt;/span>.&lt;span style="color:#a6e22e">concurrent&lt;/span>.&lt;span style="color:#a6e22e">ThreadPoolExecutor&lt;/span>.&lt;span style="color:#a6e22e">runWorker&lt;/span>(Unknown Source)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	at java.&lt;span style="color:#a6e22e">util&lt;/span>.&lt;span style="color:#a6e22e">concurrent&lt;/span>.&lt;span style="color:#a6e22e">ThreadPoolExecutor$Worker&lt;/span>.&lt;span style="color:#a6e22e">run&lt;/span>(Unknown Source)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	at java.&lt;span style="color:#a6e22e">lang&lt;/span>.&lt;span style="color:#a6e22e">Thread&lt;/span>.&lt;span style="color:#a6e22e">run&lt;/span>(Unknown Source)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>解决方案：&lt;/p></description></item><item><title>使用documents4j将转换office为pdf</title><link>https://blog.ffff65535.com/posts/2022/03/14/documents4j-office-word2pdf/</link><pubDate>Mon, 14 Mar 2022 16:43:00 +0800</pubDate><guid>https://blog.ffff65535.com/posts/2022/03/14/documents4j-office-word2pdf/</guid><description>&lt;p>使用documents4j将word、excel、ppt转换为pdf&lt;/p>
&lt;p>仅支持windows环境转换，需要安装MS office&lt;/p>
&lt;hr>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-jsx" data-lang="jsx">&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">dependency&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">groupId&lt;/span>&amp;gt;&lt;span style="color:#a6e22e">com&lt;/span>.&lt;span style="color:#a6e22e">documents4j&lt;/span>&amp;lt;/&lt;span style="color:#f92672">groupId&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">artifactId&lt;/span>&amp;gt;&lt;span style="color:#a6e22e">documents4j&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#a6e22e">local&lt;/span>&amp;lt;/&lt;span style="color:#f92672">artifactId&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">version&lt;/span>&amp;gt;&lt;span style="color:#ae81ff">1.1.7&lt;/span>&amp;lt;/&lt;span style="color:#f92672">version&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">dependency&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">dependency&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">groupId&lt;/span>&amp;gt;&lt;span style="color:#a6e22e">com&lt;/span>.&lt;span style="color:#a6e22e">documents4j&lt;/span>&amp;lt;/&lt;span style="color:#f92672">groupId&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">artifactId&lt;/span>&amp;gt;&lt;span style="color:#a6e22e">documents4j&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#a6e22e">transformer&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#a6e22e">msoffice&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#a6e22e">word&lt;/span>&amp;lt;/&lt;span style="color:#f92672">artifactId&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">version&lt;/span>&amp;gt;&lt;span style="color:#ae81ff">1.1.7&lt;/span>&amp;lt;/&lt;span style="color:#f92672">version&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">dependency&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">dependency&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">groupId&lt;/span>&amp;gt;&lt;span style="color:#a6e22e">com&lt;/span>.&lt;span style="color:#a6e22e">documents4j&lt;/span>&amp;lt;/&lt;span style="color:#f92672">groupId&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">artifactId&lt;/span>&amp;gt;&lt;span style="color:#a6e22e">documents4j&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#a6e22e">transformer&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#a6e22e">msoffice&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#a6e22e">excel&lt;/span>&amp;lt;/&lt;span style="color:#f92672">artifactId&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">version&lt;/span>&amp;gt;&lt;span style="color:#ae81ff">1.1.7&lt;/span>&amp;lt;/&lt;span style="color:#f92672">version&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">dependency&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">dependency&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">groupId&lt;/span>&amp;gt;&lt;span style="color:#a6e22e">com&lt;/span>.&lt;span style="color:#a6e22e">documents4j&lt;/span>&amp;lt;/&lt;span style="color:#f92672">groupId&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">artifactId&lt;/span>&amp;gt;&lt;span style="color:#a6e22e">documents4j&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#a6e22e">transformer&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#a6e22e">msoffice&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#a6e22e">powerpoint&lt;/span>&amp;lt;/&lt;span style="color:#f92672">artifactId&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">version&lt;/span>&amp;gt;&lt;span style="color:#ae81ff">1.1.7&lt;/span>&amp;lt;/&lt;span style="color:#f92672">version&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#f92672">dependency&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>使用的依赖&lt;/p></description></item></channel></rss>