<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>I&#39;m K.T</title>
    <link>https://kytrun.com/</link>
    <description>Recent content on I&#39;m K.T</description>
    <image>
      <title>I&#39;m K.T</title>
      <url>https://kytrun.com/favicon.ico</url>
      <link>https://kytrun.com/favicon.ico</link>
    </image>
    <generator>Hugo -- 0.147.7</generator>
    <language>zh</language>
    <lastBuildDate>Thu, 21 Mar 2024 14:38:43 +0000</lastBuildDate>
    <atom:link href="https://kytrun.com/atom.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>部署公网可访问的 AList</title>
      <link>https://kytrun.com/alist-public-deployment/</link>
      <pubDate>Thu, 21 Mar 2024 14:38:43 +0000</pubDate>
      <guid>https://kytrun.com/alist-public-deployment/</guid>
      <description>&lt;p&gt;AList 支持多个存储提供商，包括本地存储、阿里云盘、OneDrive、Google Drive 等，且易于拓展。支持以 WebDAV 协议访问。&lt;/p&gt;
&lt;p&gt;本文介绍如何使用免费资源部署一个可以在公开网络使用的 AList。&lt;/p&gt;
&lt;h3 id=&#34;1-注册-tidb-云服务账号&#34;&gt;1. 注册 TiDB 云服务账号&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;地址：&lt;a href=&#34;https://tidbcloud.com/signup&#34;&gt;https://tidbcloud.com/signup&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;官方文档：&lt;a href=&#34;https://docs.pingcap.com/zh/tidb/stable/dev-guide-build-cluster-in-cloud&#34;&gt;https://docs.pingcap.com/zh/tidb/stable/dev-guide-build-cluster-in-cloud&lt;/a&gt;&lt;/strong&gt;（只需要创建好 alist 数据库，拿到配置信息即可）&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;image-20240320155025131&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/%E9%83%A8%E7%BD%B2%E5%85%AC%E7%BD%91%E8%AE%BF%E9%97%AE%E7%9A%84%20Alist.assets/image-20240320155025131.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;2-创建-alist-数据库&#34;&gt;2. 创建 alist 数据库&lt;/h3&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/%E9%83%A8%E7%BD%B2%E5%85%AC%E7%BD%91%E8%AE%BF%E9%97%AE%E7%9A%84%20Alist.assets/create-alist-database.png&#34;&gt;
&lt;strong&gt;如图，在 &lt;code&gt;Chat2Query&lt;/code&gt; 中粘贴代码 &lt;code&gt;CREATE DATABASE alist&lt;/code&gt;，然后点击右上角的 &lt;code&gt;Run&lt;/code&gt; 执行。&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;复制数据库地址用户名和密码注意保存&#34;&gt;复制数据库地址、用户名和密码（注意保存）：&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;点击目标集群名称，进入集群概览页面，然后点击右上角的 Connect 按钮，弹出连接对话框。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/%E9%83%A8%E7%BD%B2%E5%85%AC%E7%BD%91%E8%AE%BF%E9%97%AE%E7%9A%84%20Alist.assets/connect-tidb.png&#34;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在对话框中，选择你需要的连接方式和操作系统并保存对应的连接字符串。下面连接到集群的步骤将以 MySQL 客户端为例。&lt;/p&gt;
&lt;p&gt;点击 Generate Password 生成随机密码。生成的密码不会再次显示，因此请将密码妥善保存。如果没有设置 root 密码，你将无法连接到集群。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/%E9%83%A8%E7%BD%B2%E5%85%AC%E7%BD%91%E8%AE%BF%E9%97%AE%E7%9A%84%20Alist.assets/reset-tidb-password.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;3-注册-koyeb-容器部署服务账号&#34;&gt;3. 注册 Koyeb 容器部署服务账号&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;使用 GitHub 注册：&lt;a href=&#34;https://app.koyeb.com/auth/signup&#34;&gt;https://app.koyeb.com/auth/signup&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用邮箱注册：&lt;a href=&#34;https://app.koyeb.com/auth/signup?method=email&#34;&gt;https://app.koyeb.com/auth/signup?method=email&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;image-20240320155634194&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/%E9%83%A8%E7%BD%B2%E5%85%AC%E7%BD%91%E8%AE%BF%E9%97%AE%E7%9A%84%20Alist.assets/image-20240320155634194.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;4-配置-koyeb-alist-项目&#34;&gt;4. 配置 Koyeb alist 项目&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建 Web Service 项目&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;image-20240321140434206&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/%E9%83%A8%E7%BD%B2%E5%85%AC%E7%BD%91%E8%AE%BF%E9%97%AE%E7%9A%84%20Alist.assets/image-20240321140434206.png&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;使用 Docker 镜像部署：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;image-20240321140518636&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/%E9%83%A8%E7%BD%B2%E5%85%AC%E7%BD%91%E8%AE%BF%E9%97%AE%E7%9A%84%20Alist.assets/image-20240321140518636.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>拥抱孤独的自由：个人感情观与未来生活展望</title>
      <link>https://kytrun.com/embracing-solitude-freedom/</link>
      <pubDate>Sun, 07 Jan 2024 09:46:11 +0000</pubDate>
      <guid>https://kytrun.com/embracing-solitude-freedom/</guid>
      <description>&lt;p&gt;想写此文很久了，迟迟没有动笔的原因，虚伪一点的说法是人在不断成长，阅历逐渐丰富，思想也在不断发生变化，过早发布不足以表达完整成熟的内心想法，真实的原因就是懒惰、拖延。&lt;/p&gt;
&lt;p&gt;现在的我想保持单身，不代表以后还是这样想，更不是想改变他人的想法。&lt;/p&gt;
&lt;p&gt;我是一个做足准备才会行动的人，可婚恋这件事，我可能一辈子也准备不好。&lt;/p&gt;
&lt;h1 id=&#34;思想性格&#34;&gt;思想性格&lt;/h1&gt;
&lt;p&gt;一个人的思想就像可以自我净化调和的染缸，不断吸收各种染料，混成专属这人的一种颜色。我是个畏手畏脚、谨慎敏感的人，过度关注自己，想得太多，做得太少，朱颜翠发而多愁善感，锦瑟年华却老气横秋。&lt;/p&gt;
&lt;p&gt;以我小时候的观念来看，结婚就是和一人相依相伴，白头到老，共度余生。后来逐渐意识到永远相爱这件事如同大海捞针，面对一无所知的未来，承诺永远爱一个人好像有些不可理喻。心动是出于动物本能的，是短暂的，不能指望对方永远爱自己，也无法承诺一生只爱一人。相爱时在一起，不爱了自然就该分开。两个“合适”的人就是在新鲜感消散的时候出于双方需求和责任感依然坚定地选择彼此。我的人生观念遭到自我意识的剧烈冲击，二十多年建立的认知开始崩坏瓦解，然后重塑，再不断安慰自己去接受。&lt;/p&gt;
&lt;p&gt;伟大的人类事业和未知的浩瀚宇宙使我激情澎湃，文学、艺术、音乐、影视、人工智能、机械飞升……让我对未来的每一天保持期待。精神世界丰富繁华，现实生活却了无生趣。我深谙千里之行始于足下之理，却又缺乏充实现实生活的欲望，粗茶淡饭，得过且过。&lt;/p&gt;
&lt;p&gt;我需要独立的生活和思考空间，我喜欢独处，更倾向于按照自己的节奏自在闲适地生活。如果跟喜欢的人在一起，我会害怕暴露自己的缺点，担心自己各方面做得不够好。对我来说，分寸感比亲密无间更重要，所以我更需要的不是爱人，而是挚友。爱情如泉，奔涌淋漓，干涸沉寂；友情如池，点滴存取，江湖救急。对喜欢的人会有占有欲和控制欲，而朋友的相处模式就自在很多。我希望互相欣赏的人在相处时云淡风轻而延绵不尽，不是短暂的激情过后，又相忘于江湖。&lt;/p&gt;
&lt;p&gt;再者，我不是一个乐观的人，不太能共情别人的幸福喜悦，特别能共情别人的痛苦悲伤，不在一起的时时刻刻我都会对所爱之人担忧，这会使我非常煎熬。婚姻不仅仅是身边多一个人，还要共享一份人间疾苦。我不喜欢被打扰，也不在他人身上寄托希望。人生这么多苦难，承担一个人的就够辛苦了，不如自私一点，放空自己，让生活过得尽量简单，才不会远愁近虑，杞人忧天。&lt;/p&gt;
&lt;h1 id=&#34;原生家庭&#34;&gt;原生家庭&lt;/h1&gt;
&lt;p&gt;我出生在传统的农村家庭，父母虽然通情达理，对我的教育也还算成功，但其实文化程度并不高，我踩在他们肩上看过太多外面的世界，接受了完全不一样的思想教育。事实上我完全理解他们，在他们的经历见闻和生活背景下，已经做得足够好，而且还在不断进步。我从小和他们在一起生活，可以接受和容忍他们的不足，但如果带来一个完全不在这种环境下成长的人与他们共处，还需要付出很多努力去调和，我没有充足的信心。&lt;/p&gt;
&lt;h1 id=&#34;现实&#34;&gt;现实&lt;/h1&gt;
&lt;p&gt;婚姻是彩礼嫁妆，生活是柴米油盐，“没有物质的爱情，就是一盘散沙”。我现在还没有让自己和爱的人一起安稳幸福的经济实力，虽然抱有一丝希望，但眼下看来也遥遥无期。喜欢是占有，爱是放手。如果对方可以追求更好的生活，没有理由束缚在自己的身边。我虽然在努力创造更好的生活条件，但也没有必要为了组建一个家庭累死累活。人各有志，尽力而为。&lt;/p&gt;
&lt;h1 id=&#34;憧憬&#34;&gt;憧憬&lt;/h1&gt;
&lt;p&gt;随着人们了解世界的途径越来越便捷，见过的美好的人和事越来越多，对实际生活中的人便越来越难心动。“喜欢”不过是一场或急或缓的自我心理暗示，我好像越来越难以实现这样的暗示了。遇不到合适的人就单着，遇到合适的就谈一辈子恋爱。&lt;/p&gt;
&lt;p&gt;我不是在找一个合法伴侣，或是一个贤妻良母，一个孝顺儿媳。而是一个知己，一个挚友，一个可以相互理解、相互陪伴、共同抵御未来风险的人。但这并不意味着我们必须从事相同的行业、有着共同的爱好、处于一致的社交圈。我们都应该有独立的人格、独到的见解、独特的品味。只需要在彼此内心有对方专属的位置，尊重欣赏，共同进步。哪怕新鲜感消散，即使遭遇变故，也不离不弃，如亲人般继续去爱，去陪伴，去度过漫长且枯燥的生活。&lt;/p&gt;
&lt;p&gt;幸福就是少想自己缺少什么，多想自己拥有什么。享受单身可以比很多人幸福，如果不用谈恋爱、不用结婚生子，完全为自己而活，人生还是很美好的。生活不止是未来，也是过去和现在，是每时每刻。看透一些事情以后，虽然还不能做到六根清净，但是好像真的没什么物欲了。想去做自己认为有意义的、让世间更美好的事。想云游四海，探索世界，见证奇迹，看看住在不同地方的人；想整理思绪，修身养性，把酒言欢，回归简单朴实的生活。&lt;/p&gt;
&lt;h1 id=&#34;可能面临的疑问&#34;&gt;可能面临的疑问&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;“一个人不害怕孤独吗？”&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;孤独源自内心，和周围有多少人没有关系，如果选择一个不合适的人，同床异梦，才是真正的孤独。如果两个人相爱一生，对方却不得不先你离世，反而要面临跌入谷底般的孤独。不恋不婚，平淡如水，虽然要牺牲可能的快乐，却也能躲避潜在的痛苦。孤独是人类情感的终极状态，坦然接受孤独吧。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“生病时怎么办？不生孩子自己以后老了怎么办？”&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;当人类不再需要考虑生育，恋爱才真正迈向自由。我时常庆幸自己是个男儿身，不用面临怀胎和分娩之苦，自然也不希望所爱之人遭受这样的折磨。&lt;/p&gt;
&lt;p&gt;“养儿防老”的观念在社会经济不发达、生产力水平低下的时候很实际，但在当今和未来社会不一定。如果没有足够的经济实力，一年里和父母相处不了几天，又要考虑孩子的教育和就业，老人真正被关心照顾的时候已是迟暮。这个世界缺了谁依然会转，我的基因也没有一定要延续下去的必要。&lt;/p&gt;
&lt;p&gt;如果不要孩子，可以宽裕地生活，关照家人，更多地投资在身心健康和享乐上。自己老的时候科技发展成什么样不一定，但大概率医疗和养老保障水平会提高，和如今社会的儿女照料不好比较，应该也不至于特别糟。如果世界真的会变糟，又何必带孩子出来受苦呢？这个世界还不够好，有多少人因为苦难常希望没来过这个世界，我们实现不了，不如帮孩子实现了。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“你想太多了太悲观了，这个世界上肯定有欣赏你理解你支持你、愿意跟你共度一生的人。”&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;我当然希望如此，毕竟，哪有人喜欢孤独，只是害怕失望。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java 参数校验：只能从指定的值中取其一</title>
      <link>https://kytrun.com/java-validation-one-of/</link>
      <pubDate>Thu, 17 Nov 2022 19:37:48 +0000</pubDate>
      <guid>https://kytrun.com/java-validation-one-of/</guid>
      <description>&lt;p&gt;有时候参数校验的需求是只允许从指定的几个数据中选用一个，否则抛出异常。&lt;/p&gt;
&lt;p&gt;如果是 &lt;code&gt;String&lt;/code&gt; 类型的可以用 &lt;code&gt;@Pattern&lt;/code&gt; 注解写正则表达式，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@Pattern&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;regexp&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;^(CENTURIES|YEARS|MONTHS|DAYS)$&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;持续时间单位错误&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;durationUnit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;数字类型可以通过自定义注解 + 校验规则。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;OneOf.java&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Target&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FIELD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PARAMETER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@Retention&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RUNTIME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@Constraint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;validatedBy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OneOfValidator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@Documented&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@Repeatable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@interface&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OneOf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Invalid parameter&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;?&amp;gt;[]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;extends&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Payload&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;[]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;payload&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 用 double 接收可用值，兼容整数和小数&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@Target&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FIELD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PARAMETER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@Retention&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RUNTIME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@Documented&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@interface&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OneOf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;OneOfValidator.java&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Nacos 元数据增加启动日期、版本号和 PID</title>
      <link>https://kytrun.com/nacos-add-metadata/</link>
      <pubDate>Mon, 19 Sep 2022 19:43:24 +0000</pubDate>
      <guid>https://kytrun.com/nacos-add-metadata/</guid>
      <description>&lt;p&gt;Spring Cloud 项目下 Nacos 默认的元数据只有 &lt;code&gt;preserved.register.source=SPRING_CLOUD&lt;/code&gt; 这一项，可以通过增加配置项手动添加想要的数据，方便追溯一些启动相关的信息。&lt;/p&gt;
&lt;p&gt;比如：启动日期、文件版本号（因为打成 jar 包时 maven 插件会将文件名自动命名为 xxx-{version}.jar，所以这里是获取的 jar 文件路径）和 PID。&lt;/p&gt;
&lt;p&gt;代码如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Configuration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;NacosConfig&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * Nacos 元数据配置
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * @return
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     */&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@Bean&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@ConditionalOnNacosDiscoveryEnabled&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NacosDiscoveryProperties&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nacosDiscoveryProperties&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NacosDiscoveryProperties&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nacosDiscoveryProperties&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NacosDiscoveryProperties&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Map&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nacosDiscoveryProperties&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getMetadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 启动时间&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;put&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;boot.startup.time&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SimpleDateFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;yyyy-MM-dd HH:mm:ss&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;currentTimeMillis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()));&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 文件路径&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// String.valueOf 代替 toString 避免空指针&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;put&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;boot.path&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;valueOf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ApplicationHome&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getClass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getSource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()));&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// PID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;put&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;boot.pid&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ApplicationPid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nacosDiscoveryProperties&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nacos 控制台的实例可以看到类似如下的元数据：&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spring Boot 带附件的邮件发送配置</title>
      <link>https://kytrun.com/spring-boot-attachment-mail-sender/</link>
      <pubDate>Mon, 25 Jul 2022 16:08:23 +0000</pubDate>
      <guid>https://kytrun.com/spring-boot-attachment-mail-sender/</guid>
      <description>&lt;p&gt;虽然 Spring Boot 提供了邮件相关的功能，但在缺少部分配置的情况下或多或少会有一些问题，如附件的文件名乱码、文件格式等问题。本文提供统一解决这类问题的配置。&lt;/p&gt;
&lt;p&gt;Maven 依赖：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-mail&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;1-配置文件&#34;&gt;1. 配置文件&lt;/h2&gt;
&lt;p&gt;以 QQ 邮箱为例：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;spring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;smtp.qq.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;465&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;username&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example@qq.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 发送邮箱账户&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;password&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;exmaplepassword&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 申请的授权码&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;properties&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;smtp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;socketFactory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;465&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;javax.net.ssl.SSLSocketFactory&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ssl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;starttls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;required&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;2-封装统一工具类&#34;&gt;2. 封装统一工具类&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt; * @author Kytrun
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt; * @version 1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt; * @date 2022/07/25 16:14
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt; */&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@RequiredArgsConstructor&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@Component&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;MailUtil&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;final&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JavaMailSender&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailSender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@Value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;${spring.mail.username}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailFrom&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 长文件名不截断&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getProperties&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setProperty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;mail.mime.splitlongparameters&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;false&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * 发送纯文字邮件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * @param to      收件地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * @param subject 主题
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * @param text    内容
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     */&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;send&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SimpleMailMessage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailMessage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SimpleMailMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setTo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setSubject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setSentDate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setText&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setFrom&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailFrom&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailSender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;send&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * 发送带多个附件的邮件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * @param to       收件地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * @param subject  主题
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * @param text     文字内容
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * @param fileList 文件列表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * @throws MessagingException
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     * @throws UnsupportedEncodingException
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;     */&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;send&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MultipartFile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileList&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;throws&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MessagingException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UnsupportedEncodingException&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MimeMessage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mimeMessage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailSender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;createMimeMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MimeMessageHelper&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messageHelper&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MimeMessageHelper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mimeMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messageHelper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setFrom&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailFrom&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messageHelper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setTo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messageHelper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setSubject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messageHelper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setText&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileList&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileList&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;isEmpty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MultipartFile&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileList&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileName&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getOriginalFilename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;文件&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getOriginalFilename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//解决中文附件名的问题&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileName&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MimeUtility&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;encodeText&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messageHelper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;addAttachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailSender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;send&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mimeMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Spring Cloud Feign 去除全局包装、统一异常处理</title>
      <link>https://kytrun.com/spring-cloud-feign-unwrap-and-exception/</link>
      <pubDate>Wed, 13 Jul 2022 14:48:28 +0000</pubDate>
      <guid>https://kytrun.com/spring-cloud-feign-unwrap-and-exception/</guid>
      <description>&lt;p&gt;2022 年关于 Spring Cloud 服务间调用组件 Feign 配置的总结。&lt;/p&gt;
&lt;p&gt;Maven 依赖：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.cloud&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-cloud-starter-openfeign&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;1-全局响应包装的拆解&#34;&gt;1. 全局响应包装的拆解&lt;/h2&gt;
&lt;p&gt;一般来说，我们服务接口响应内容都有一层全局的包装，比如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;code&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;message&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;成功&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在服务间调用时如果在每个 Feign 的接口处定义同样的类比如 &lt;code&gt;Result&amp;lt;XxVO&amp;gt;&lt;/code&gt; 再 &lt;code&gt;getData()&lt;/code&gt; 不是不行，但是比较繁琐，而且在获取想要的数据前可能需要根据 &lt;code&gt;code&lt;/code&gt;、&lt;code&gt;message&lt;/code&gt; 判断得到的结果是否正确。通过自定义 &lt;code&gt;decoder&lt;/code&gt; 可以比较好地解决前一个问题：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 注入 Jackson 的 ObjectMapper，如果不喜欢 Lombok 可以自行修改&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@RequiredArgsConstructor&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;UnwrapDecoder&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;implements&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Decoder&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;final&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ObjectMapper&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;objectMapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@SneakyThrows&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@Override&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Object&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Reader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;asReader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Charset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;defaultCharset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;?&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;objectMapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;readValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 根据 code 判断操作是否成功&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ResultCode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;isSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getCode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Object&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JavaType&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;javaType&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TypeFactory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;defaultInstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;constructType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;objectMapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;convertValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;javaType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 若不成功，抛出业务异常，注意此处的异常会在 DecodeException 中被捕获，后文会处理&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;throw&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BusinessException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getCode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;使用方式：&lt;/p&gt;</description>
    </item>
    <item>
      <title>这七年</title>
      <link>https://kytrun.com/7-years/</link>
      <pubDate>Sat, 01 Jan 2022 16:58:22 +0000</pubDate>
      <guid>https://kytrun.com/7-years/</guid>
      <description>&lt;p&gt;今天是 2022 年 1 月 1 日，在这里回顾一下 2015 年高考到现在的 7 年时光。&lt;/p&gt;
&lt;h2 id=&#34;1-备战高考&#34;&gt;1. 备战高考&lt;/h2&gt;
&lt;p&gt;2015 年，我在四川省绵阳市三台中学准备高考，因为学校的严格管理加自身平时也还算自律，没有什么太多的值得回忆的，好像除了在紧张忙碌的学业之余唯有玩 K 歌软件了，那时常常在周末宿舍空无一人时见缝插针地录几首，然后缩在宿舍走廊的尽头连上仅仅一格信号的 WiFi 上传、听别人的歌、评论互动之类的。&lt;/p&gt;
&lt;p&gt;对于我来说高考应该是人生中第二次“千军万马过独木桥”，第一次当然是中考。我从来就没有考虑过复读之类的事情，我认为复读再上大学就相当于少活了一年，以至于后来虽然考的还行但是因为把所有的志愿都填的信息技术、电子之类的且没有勾选任何的调剂而落榜了。好在恰逢重庆理工大学两江国际学院收的人数不够，而这个新开设的学院是中韩合作办学的第一年，只开设“计算机科学与技术”和“电子信息科学与技术”两个专业。我理所当然地填报了，本来收到录取消息的时候还很高兴，但当得知一年 2.8 万的学费的时候把自己关进屋里狠狠哭了一场。可是无论如何，我还是进到了 IT 领域，我认为这是我人生的必然。感谢父母培育之恩。&lt;/p&gt;
&lt;h2 id=&#34;2-步入大学&#34;&gt;2. 步入大学&lt;/h2&gt;
&lt;p&gt;进到大学首先面临的是全英文教学的艰苦岁月了，除了思政和体育课，其他几乎所有基础课程和专业课程都是全英文。上完第一节全英文高数课之后向室友和家长哭诉，然后直接办理退学那位大学同学的形象在我脑海中依然深刻。&lt;/p&gt;
&lt;p&gt;一堂口语课七八个人，和外教聊各种与英语本身几乎没什么关系的趣事，我无人能敌的猜谜语技能，课堂上各种小游戏、角色扮演…… 还有和蔼可亲而不失严肃认真的韩国教授、温柔的辅导员姐，每天晚上的托福培训…… 现在回想，那时候的老师、同学和时光还是挺美好的。&lt;/p&gt;
&lt;p&gt;我依然没有放弃音乐相关的业余爱好。获得人生中第一台电脑之后，在一个国庆假期凭着激情快速学习音频编辑，然后买录音设备，仍然在课余躲在宿舍录歌，那是我为数不多的娱乐活动，甚至超过了主业。沉浸在音乐世界放飞自我的无数个夜晚，感谢隔壁宿舍同学的不杀之恩。&lt;/p&gt;
&lt;p&gt;2016 年 - 2017 年是大二，这一年好像和大一的差别不大，该去往韩国交换或者留学的同学都还在。仅仅是确认了自己不可能出国而逐渐降低自身对英语的要求。录音混音的技能逐渐成熟，开始有了较高质量的翻唱作品，后来也收获过小一两千的粉丝数。还有每次编程大作业的拖延与熬夜，考试前的临时抱佛脚……&lt;/p&gt;
&lt;p&gt;2018 年左右大三这年，厉害的同学去了国外深造，而我自己的专业能力乏善可陈，逐渐开始有了危机感。嗓子也有了一些变化，没有以前那么青涩和稚嫩，也唱不了很多难度一般的歌曲，后来发现唱《叶塞尼亚》这样的低音歌曲好像还不错。日积月累的伏案混音造成了颈椎对我的反抗，时间稍长就会疼痛。在音乐圈子里积累的朋友的帮助下，我实现了发表一首原创歌曲的梦想之后逐渐放下了音乐，暂停吧，该为自己的未来考虑了。&lt;/p&gt;
&lt;p&gt;2019 年，大四，和其他学院不太一样，我们仍然有好几门课程，完全没有去企业实习的经历。我拿了驾照，考过了四六级，无一门挂科记录，最后还算体面的毕业了。因为学院人少且地理位置偏僻，来校招的企业单位寥寥无几，所幸的是最后还是去了一所在当时来说还算满意的公司，我和几位同学从重庆来到了离我家更近的地方——成都。&lt;/p&gt;
&lt;h2 id=&#34;3-开始就业&#34;&gt;3. 开始就业&lt;/h2&gt;
&lt;p&gt;在公司环境下技术能力的提升是飞快的，起初我做的是前端，那时因为上司的原因最早接触的是 Ext JS，现在看来这似乎是一个不太明智的选型，没过多久我们就换到了 jQuery + Layui。而且这段时间天天坐一个半小时的公交去很远的地方上班，现在想想仍然心累。持续了几个月之后，终于可以只需要 10 分钟通勤时间正常地到公司上班了。虽然我对前端的理解日益深刻，但我也由前端转为 Java 后端了，还好，这次学的 Spring Cloud。&lt;/p&gt;
&lt;p&gt;这一年我逐渐接触到了开源社区，为了解决自己在工作生活中的问题，也开始自己做一些前端相关的作品发布在 GitHub 上。&lt;/p&gt;
&lt;p&gt;2020 年 - 2021 年 8 月，这将近两年的时间里凭借和同事的交流以及自己的学习积累，算是后端入门了。公司给自己带来的技术提升不算特别大，可最终我也算十多个后端开发人员当中的头部选手了，偶尔参与架构的调整设计，帮助一些新来的同事等。&lt;/p&gt;
&lt;p&gt;从高中以来我一直梦想着能够开发出好用的手机 APP，于是我一直关注着移动端跨平台开发技术，了解 React Native 和 Flutter 的区别，学习 VUE 和 UNI-APP。平时自己做点 demo，不过目前没有成熟的产品上线，但一直思考着该如何做点真正有用的软件。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spring Cloud 不停机更新 – shell 脚本</title>
      <link>https://kytrun.com/spring-cloud-graceful-update/</link>
      <pubDate>Tue, 28 Dec 2021 09:31:51 +0000</pubDate>
      <guid>https://kytrun.com/spring-cloud-graceful-update/</guid>
      <description>&lt;p&gt;本文简单介绍关于 Spring Cloud 技术栈的对外无感知的优雅停机、更新和重启，仅通过一些微服务组件和 shell 脚本实现，不依赖容器技术。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 实现原理&lt;/strong&gt;
实现对外透明的优雅更新的基本原理就是在原服务没有停机的时候启动一个新的进程，通过负载均衡让访问可以到达两个节点，然后将旧的服务“优雅”地下线，其本质是不接收新的请求，同时将正在处理中的请求完成，然后停机，之后的请求全部路由到新的服务上。
&lt;strong&gt;2. 服务架构&lt;/strong&gt;
实现以上方案主要依靠 Spring Gateway 和 Nacos。
Spring Gateway 聚合内部的服务接口向外暴露，所有服务注册在 Nacos 上，在 Spring Gateway 上配置好 Nacos 使其动态路由到具体的服务而非写死 IP 和端口。
&lt;strong&gt;3. 具体细节&lt;/strong&gt;
首先，优雅下线的配置是最简单的，在 Spring  Boot 的配置文件中添加&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;server&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shutdown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;graceful&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;（Spring Boot 2.3+ 支持）
然后在停机时用 &lt;code&gt;kill&lt;/code&gt; 命令就可以了，配置了优雅下线后会关闭各种连接、释放资源并主动从 Nacos 中注销。需要特别注意的是不能使用 &lt;code&gt;kill -9&lt;/code&gt; 强制杀进程。&lt;/p&gt;
&lt;p&gt;然后，因为需要能够在同一时间内运行两个服务，所以我们需要给它们指定不同的端口，一种较为简单的方式是在配置文件中将 &lt;code&gt;server.port&lt;/code&gt; 配置为 0，这样启动时就会在本机没有占用的端口中随机使用一个，但缺点是无法指定端口的范围，因而我使用的是另一种方式，即在 shell 脚本中寻找一个端口然后在 jar 包的启动参数中指定。&lt;/p&gt;
&lt;p&gt;shell 编写的大体思路是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;找到一个在指定范围内没被占用的端口，开启新的服务。&lt;/li&gt;
&lt;li&gt;找到旧版本的进程然后 kill 关闭。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;按道理说这样就行了，但是我在实际测试中发现在旧服务关闭的短暂时间内会有 Gateway 仍然路由到旧服务然后报错的情况，当前的解决方案是在关闭服务前先调用 Nacos 的 API 将旧实例从中注销，过一段时间后再杀掉进程，还需要一段时间考察。&lt;/p&gt;</description>
    </item>
    <item>
      <title>使用 preload 资源预加载</title>
      <link>https://kytrun.com/use-preload/</link>
      <pubDate>Sat, 19 Sep 2020 22:02:07 +0000</pubDate>
      <guid>https://kytrun.com/use-preload/</guid>
      <description>&lt;p&gt;如果有前后关联的异步 XHR 请求通常会在回调函数中按顺序先后加载，但这样会比较耗时，所以我们有 &lt;code&gt;Promise.all()&lt;/code&gt; 来并行请求，最后再处理。&lt;/p&gt;
&lt;p&gt;在编写小型前端项目尽可能考虑兼容且不依赖第三方库时，可以使用在 html 的 &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; 中添加 &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; 通过 &lt;code&gt;rel=&amp;quot;preload&amp;quot;&lt;/code&gt; 进行内容预加载。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; 元素的 rel 属性的属性值 preload 能够让你在你的 HTML 页面中 &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;元素内部书写一些声明式的资源获取请求，可以指明哪些资源是在页面加载完成后即刻需要的。对于这种即刻需要的资源，你可能希望在页面加载的生命周期的早期阶段就开始获取，在浏览器的主渲染机制介入前就进行预加载。这一机制使得资源可以更早的得到加载并可用，且更不易阻塞页面的初步渲染，进而提升性能。
&amp;ndash;引用自 &lt;a href=&#34;https://developer.mozilla.org/zh-CN/docs/Web/HTML/Preloading_content&#34;&gt;MDN&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;简单来说，就是添加这种特定的 head 后我们就可以在文档加载后就提前请求一部分内容，留待之后的网络请求直接使用，不需要额外的处理。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;串行请求：&lt;/em&gt;
&lt;img alt=&#34;xhr_serial&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/xhr_serial.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;并行请求：&lt;/em&gt;
&lt;img alt=&#34;xhr_parallel&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/xhr_parallel.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;为了动态的添加 &amp;ldquo;preload&amp;rdquo;，还可以通过 js 代码实时写入到 DOM 中，以下是我封装的函数。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;preload&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;preloadLink&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;link&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;preloadLink&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;href&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;preloadLink&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;rel&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;preload&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;preloadLink&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;fetch&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;preloadLink&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;crossOrigin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;anonymous&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;appendChild&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;preloadLink&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Spring Boot 打包为 exe 安装文件</title>
      <link>https://kytrun.com/spring-boot-exe-package/</link>
      <pubDate>Mon, 06 Jul 2020 20:51:25 +0000</pubDate>
      <guid>https://kytrun.com/spring-boot-exe-package/</guid>
      <description>&lt;p&gt;在工作中可能会遇到单机使用的 Java Web 项目。从可移植性、可扩展性、学习成本等各方面来看，使用 Spring Boot 搭建都是一个不错的选择，而且如果后期调整为云部署也是非常容易。&lt;/p&gt;
&lt;p&gt;虽然 Spring Boot 天然支持打成 jar 包，但是对于用户来说，启动方式还是不够“优雅”。如果封装为一个独立的安装包，有快捷方式，双击运行，那么体验就更接近 APP 了。&lt;/p&gt;
&lt;p&gt;在调研了多种方式后，使用以下的方案是我认为还算 OK 的一种，遂记录下来。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;创建一个文件夹，放入 jar 包和 jre 文件夹；&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/jar-setup-1.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;这里有两种方式，我是直接将 jre 一起打包，也可以独立安装 Java。&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;
&lt;p&gt;编写一个 bat 批处理文件，内容如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;@echo off
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;start jre1.8.0_251&lt;span class=&#34;se&#34;&gt;\b&lt;/span&gt;in&lt;span class=&#34;se&#34;&gt;\j&lt;/span&gt;ava.exe -jar swagx-0.0.1-SNAPSHOT.jar
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;explorer http://localhost:8080
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中 &lt;code&gt;jre1.8.0_251\bin\java.exe&lt;/code&gt; 为 Java 的路径，&lt;code&gt;swagx-0.0.1-SNAPSHOT.jar&lt;/code&gt; 为 jar 的文件名称，&lt;code&gt;http://localhost:8080&lt;/code&gt; 为项目启动主页，也可以添加静态 html 文件等，启动时改为 index.html 之类的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后将 bat 文件放入目录，建议命名为应用名称；&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/jar-setup-2.png&#34;&gt;&lt;/p&gt;
&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;使用 &lt;a href=&#34;https://jrsoftware.org/isinfo.php&#34;&gt;Inno Setup&lt;/a&gt; 软件打包，网上教程很多；&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/inno-setup-1.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;注意执行文件选择 bat 脚本：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/inno-setup-2.png&#34;&gt;&lt;/p&gt;
&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;在文件夹中放入 &lt;code&gt;.ico&lt;/code&gt; 格式的图标文件，在 Inno Setup 生成的代码中添加图标配置：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/inno-setup-3.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>接口调试神器 Network&#43;</title>
      <link>https://kytrun.com/network-plus/</link>
      <pubDate>Tue, 02 Jun 2020 21:55:18 +0000</pubDate>
      <guid>https://kytrun.com/network-plus/</guid>
      <description>&lt;p&gt;浏览器自带的开发者工具 Network 只能查看网络请求但不能修改，有时候只需要修改少量的参数也需要打开第三方工具如 Postman 将 URL、method、Request Body 等完整地填写一遍。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/ClearStudio/network-plus&#34;&gt;Network+&lt;/a&gt; 是一款可以捕获、修改并重新请求的浏览器扩展，用以提升接口调试的效率。&lt;/p&gt;
&lt;p&gt;支持 Chrome、Firefox 和新版本的 Edge。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Network+&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/ClearStudio/network-plus/images/screen_recording.gif&#34;&gt;&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a href=&#34;https://github.com/ClearStudio/network-plus&#34;&gt;https://github.com/ClearStudio/network-plus&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>赞赏</title>
      <link>https://kytrun.com/donate/</link>
      <pubDate>Thu, 02 Apr 2020 20:39:17 +0000</pubDate>
      <guid>https://kytrun.com/donate/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/pay_qrcode.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>使用 Iconfont 图标</title>
      <link>https://kytrun.com/use-iconfont/</link>
      <pubDate>Wed, 01 Apr 2020 20:08:22 +0000</pubDate>
      <guid>https://kytrun.com/use-iconfont/</guid>
      <description>&lt;p&gt;在做前端项目、个人网站……时难免需要图标，Iconfont 是我认为目前最好的方案：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;图标来源于设计师、网友，图标多、全；&lt;/li&gt;
&lt;li&gt;强大的自定义功能；&lt;/li&gt;
&lt;li&gt;按需配用，不需要加载冗余资源；&lt;/li&gt;
&lt;li&gt;可以上传自己的图标，统一管理；&lt;/li&gt;
&lt;li&gt;阿里的免费 CDN；&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;可以称得上一个好用且免费的图标工厂了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用步骤&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;访问 &lt;a href=&#34;https://www.iconfont.cn&#34;&gt;https://www.iconfont.cn&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用关键字搜索图标
&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/iconfont-search.png&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;挑选喜欢的图标，悬浮在图标上添加入库
&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/iconfont-add.png&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;挑选完毕后，添加到一个项目
&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/iconfont-project.png&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;可以编辑颜色、尺寸、名称等
&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/iconfont-edit.png&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;可以自定义项目中的 font-class
&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/iconfont-project-menu.png&#34;&gt;
&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/iconfont-project-edit.png&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;生成并复制代码
&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/iconfont-code.png&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;注意：添加或编辑了项目内容后需要重新生成代码&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;参考官方使用教程 &lt;a href=&#34;https://www.iconfont.cn/help/detail?helptype=code&#34;&gt;https://www.iconfont.cn/help/detail?helptype=code&lt;/a&gt;，推荐 font-class 方式引用；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/iconfont-help-font-class.png&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;推荐直接使用 CDN，当然，如果不放心可以下载离线版备份；&lt;/li&gt;
&lt;li&gt;更多用法请自行挖掘 ；&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>独立掌控自己的信息渠道</title>
      <link>https://kytrun.com/information-master/</link>
      <pubDate>Wed, 04 Mar 2020 21:33:24 +0000</pubDate>
      <guid>https://kytrun.com/information-master/</guid>
      <description>&lt;p&gt;最近接触了又一个不那么大众的信息来源途径 - &lt;a href=&#34;https://baike.baidu.com/item/%E6%92%AD%E5%AE%A2/202513&#34;&gt;播客&lt;/a&gt;，有感于目前我的信息管理模式，遂写此文。&lt;/p&gt;
&lt;p&gt;微信公众号、新浪微博、哔哩哔哩、短视频、直播&amp;hellip; 相较于博客、播客、RSS&amp;hellip; 仿佛已经划分了两个不同的时空，信息高速发展的 2020 年代，我们将如何继续愉快地 Surf the Internet？&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;social-media&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/social-media.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如何评判信息平台化的利与弊？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我们正处于一个不那么“Open”的网络世界，因为少数的互联网大佬几乎占据了我们生活的全部，各大公司将我们身边的所有领域包揽，衣食住行、生活工作，一样不落。诚然这给我们的生活带来了很多的便捷，但我们自己也正在逐渐被吞噬、被占领。设想如果某一天微信的服务器宕机，或者视频平台被查封，亦或是支付宝的账户系统出现错误，我们受到的影响会是多大？&lt;/p&gt;
&lt;p&gt;作为一个“非典型”程序员，我是如何掌握自己的信息渠道的？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://sspai.com/post/56198&#34;&gt;RSS&lt;/a&gt; 订阅独立博客、歌手专辑、网站更新、Google Play 软件更新等，目前使用 &lt;a href=&#34;https://rsshub.app/&#34;&gt;RSSHub&lt;/a&gt; 生成 RSS 订阅源，&lt;a href=&#34;https://inoreader.com/&#34;&gt;Inoreader&lt;/a&gt; 作为订阅工具，手机端使用 &lt;a href=&#34;https://www.coolapk.com/apk/com.seazon.feedme&#34;&gt;FeedMe&lt;/a&gt; + Inoreader 账号；&lt;/li&gt;
&lt;li&gt;播客 + 泛用型播客客户端，目前使用 &lt;a href=&#34;https://moon.fm/&#34;&gt;Moon.FM&lt;/a&gt;；&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tophub.today&#34;&gt;今日热榜&lt;/a&gt; - 各站热榜聚合：微信、今日头条、知乎、微博、豆瓣等；&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://coolapk.com&#34;&gt;酷安&lt;/a&gt; - 安卓论坛 + APP 下载；&lt;/li&gt;
&lt;li&gt;微信公众号；&lt;/li&gt;
&lt;li&gt;新浪微博；&lt;/li&gt;
&lt;li&gt;哔哩哔哩；&lt;/li&gt;
&lt;li&gt;网易云音乐；&lt;/li&gt;
&lt;li&gt;Telegram 频道；&lt;/li&gt;
&lt;li&gt;即时聊天群组：QQ群、微信群、Telegram 群等；&lt;/li&gt;
&lt;li&gt;网站；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Manage:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OneDrive，坚果云，&lt;a href=&#34;https://kytrun.com/webdav/&#34;&gt;WebDAV&lt;/a&gt; 等；&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://yuque.com&#34;&gt;语雀&lt;/a&gt; - 搭配 &lt;a href=&#34;https://clipper.website/&#34;&gt;WebClipper&lt;/a&gt; 网页文章剪藏生成 Markdown 存放；&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://bishouapp.com&#34;&gt;必收&lt;/a&gt; - 网页文章自动精简格式+云端转存，补充 WebClipper 没有手机端的缺陷；&lt;/li&gt;
&lt;li&gt;GitHub 私有库；&lt;/li&gt;
&lt;li&gt;本地硬盘；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kytrun.com/&#34;&gt;独立博客&lt;/a&gt;，如你所见；&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kytrun&#34;&gt;GitHub 主页&lt;/a&gt;， 作为菜鸟程序员，却是 GitHub 重度使用者；&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kytrun.com/my-music-platforms/&#34;&gt;音乐平台&lt;/a&gt; - 大学录过几首歌，毕业之前就搁置了，希望有机会捡起；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很庆幸，我没有依赖于某一个或者一类发布平台，所有的产出 / 作品都真正握在自己手中，即使上述任何一家平台倒闭，我也几乎不受影响，顶多完全由自己搭建管理发布。&lt;/p&gt;</description>
    </item>
    <item>
      <title>GitHub &#43; jsDelivr 图床方案</title>
      <link>https://kytrun.com/github-jsdelivr-img-hosting/</link>
      <pubDate>Sat, 01 Feb 2020 22:03:50 +0000</pubDate>
      <guid>https://kytrun.com/github-jsdelivr-img-hosting/</guid>
      <description>&lt;p&gt;使用 GitHub 作为图床的优点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;方便管理，支持增删改查；&lt;/li&gt;
&lt;li&gt;Git 的全部特性；&lt;/li&gt;
&lt;li&gt;稳定，不容易失效；&lt;/li&gt;
&lt;li&gt;用 &lt;a href=&#34;https://github.com/marketplace/imgbot&#34;&gt;Imgbot&lt;/a&gt; 支持图片上传后自动压缩；&lt;/li&gt;
&lt;li&gt;免费。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;缺点：国内访问速度慢。&lt;/p&gt;
&lt;p&gt;好在 jsDelivr 提供了对 &lt;a href=&#34;https://www.jsdelivr.com/?docs=gh&#34;&gt;GitHub&lt;/a&gt; 的 CDN 加速服务，在世界各地都有服务器，极大提升了 GitHub 上静态资源的访问速度。
&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/www.jsdelivr.com__docs=gh.png&#34;&gt;
&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/jsdelivr_cdn.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;于是用 GitHub+jsDelivr 作为图床是一种较好的方案。&lt;/p&gt;
&lt;p&gt;目前已经有各种方便的 GitHub 图床工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Molunerfinn/PicGo&#34;&gt;PicGo&lt;/a&gt; - 支持含 GItHub 等多图床服务的 Windows、Mac、Linux 软件；&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jrainlau/picee&#34;&gt;Picee&lt;/a&gt; - 支持 GitHub 图床的 Chrome Extension，目前不支持转换为 jsDelivr CDN，已经向作者提了 issue；
&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为了方便使用，我将 Picee 改为了在线的 PWA 版本，并自动转换为 jsDelivr CDN 的链接，手机浏览器也能使用：&lt;a href=&#34;https://picee.clear.studio&#34;&gt;https://picee.clear.studio&lt;/a&gt;。PWA 会离线 APP 本身的资源到本地，极速加载，还可以固定到开始菜单，任务栏和桌面。
&lt;img alt=&#34;image&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/Picee_web.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;最后，我用 PicGo 的插件 &lt;a href=&#34;https://github.com/PicGo/picgo-plugin-pic-migrater&#34;&gt;picgo-plugin-pic-migrater&lt;/a&gt; 一键将博客文章 markdown 的图床统一迁移到了 GitHub。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;2020/12/16 更新：发现 Flutter 移动端 PicGo：&lt;a href=&#34;https://github.com/PicGo/flutter-picgo&#34;&gt;Flutter-PicGo&lt;/a&gt;，一个用于快速上传图片并获取图片URL链接的手机版工具。
&lt;img alt=&#34;Flutter-PicGo&#34; loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/Flutter-PicGo.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>WebDAV - 跨平台的文件资源管理协议</title>
      <link>https://kytrun.com/webdav-protocol/</link>
      <pubDate>Sun, 15 Dec 2019 17:35:54 +0000</pubDate>
      <guid>https://kytrun.com/webdav-protocol/</guid>
      <description>&lt;p&gt;WebDAV 是一个非常方便的跨平台文件共享协议，实现了 WebDAV 标准的网盘可以应用在任意支持 WebDAV 的 APP 中，提供跨平台的存储空间。&lt;/p&gt;
&lt;p&gt;我们来看专业的 &lt;a href=&#34;https://zh.wikipedia.org/wiki/%E5%9F%BA%E4%BA%8EWeb%E7%9A%84%E5%88%86%E5%B8%83%E5%BC%8F%E7%BC%96%E5%86%99%E5%92%8C%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6&#34;&gt;Wikipedia&lt;/a&gt; 是如何描述 WebDav 的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;WebDAV 协议为用户在&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E6%9C%8D%E5%8A%A1%E5%99%A8&#34; title=&#34;服务器&#34;&gt;服务器&lt;/a&gt;上创建，更改和移动文档提供了一个框架。WebDAV 协议最重要的功能包括维护作者或修改日期的属性、&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4&#34; title=&#34;名字空间&#34;&gt;名字空间&lt;/a&gt;管理、集合和覆盖保护。维护属性包括创建、删除和查询文件信息等。&lt;strong&gt;名字空间管理&lt;/strong&gt;处理在服务器名称空间内复制和移动网页的能力。&lt;strong&gt;集合&lt;/strong&gt;（Collections）处理各种资源的创建、删除和列举。&lt;strong&gt;覆盖保护&lt;/strong&gt;处理与锁定文件相关的方面。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;？？？看不懂。。。&lt;/p&gt;
&lt;p&gt;下面我就用一个通俗易懂不太恰当的比喻来解释到底什么是 WebDAV。&lt;/p&gt;
&lt;p&gt;设想如果市面上每一台设备都使用独特设计的插头，所有人的手机都没办法共享数据线，甚至自己的不同手机之间都必须使用原装，那该是多么悲惨的事情。&lt;/p&gt;
&lt;p&gt;好在现实生活中大多数充电线、数据线等都使用了标准 USB 接口，用以连接电脑、充电插头等。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/1576412482887.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;我们统一使用这个插头，连接任何一台电脑，拷贝文件资料都完美兼容，相当方便。&lt;/p&gt;
&lt;p&gt;所以，WebDAV 就好比这个统一规范的接口，一些网盘提供商遵循这套协议实现了这个接口，那么用户就可以在第三方应用中使用这个接口来连接到相应的网盘进行文件写入、查看等。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/1576458713656.svg&#34;&gt;&lt;/p&gt;
&lt;p&gt;目前支持 WebDAV 的云盘提供商不多，国内大名鼎鼎的&lt;a href=&#34;http://www.jianguoyun.com/s/content/3991.html&#34;&gt;坚果云&lt;/a&gt;，国外有 &lt;a href=&#34;https://disk.yandex.com/&#34;&gt;Yandex&lt;/a&gt;，&lt;a href=&#34;https://teracloud.jp/en/&#34;&gt;TeraCLOUD&lt;/a&gt; 等，更多请参考&lt;a href=&#34;https://www.coolapk.com/feed/10395543?shareKey=OTllZWZkNWY4NGJlNWNlZTUyN2Q~&amp;amp;shareUid=1105007&amp;amp;shareFrom=com.coolapk.market_9.2.1&#34;&gt;酷安@傲娇炎魔大螺丝 的文章&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;市面上支持使用 WebDAV 的应用有哪些呢？下面就我目前所知道的简单列举一下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Chrome 扩展:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.tampermonkey.net/&#34;&gt;Tampermonkey&lt;/a&gt; - 一款神器，用以运行各种用户开发的 JavaScript 网页脚本;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Kenshin/simpread&#34;&gt;简悦 - SimpRead&lt;/a&gt;，精简文章页面，支持保存到云盘;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/marcelklehr/floccus&#34;&gt;Floccus&lt;/a&gt;，跨浏览器书签备份;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Android APP:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.coolapk.com/apk/me.tshine.easymark&#34;&gt;易码&lt;/a&gt;， 一款支持云盘备份的笔记应用;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.coolapk.com/apk/com.merpyzf.xmnote&#34;&gt;书伴&lt;/a&gt;，一款内置 OCR 文本识别功能的书摘管理应用，自带基于 WebDAV 协议的云备份。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.mixplorer.com/&#34;&gt;Mixplore&lt;/a&gt;，体积精简但造型美观功能强大的文件管理器，可以连接各种云盘。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以上是我知道的支持 WebDAV 的网盘和平时使用较多的支持 WebDAV 的应用程序，欢迎补充。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>发布音乐的平台</title>
      <link>https://kytrun.com/my-music-platforms/</link>
      <pubDate>Sun, 15 Dec 2019 11:39:06 +0000</pubDate>
      <guid>https://kytrun.com/my-music-platforms/</guid>
      <description>&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;平台&lt;/th&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;链接&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;网易云音乐&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;a href=&#34;https://kytrun.com/to/m/netease&#34;&gt;https://kytrun.com/to/m/netease&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;QQ音乐&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;a href=&#34;https://kytrun.com/to/m/qq&#34;&gt;https://kytrun.com/to/m/qq&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;5sing&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;a href=&#34;https://kytrun.com/to/m/5sing&#34;&gt;https://kytrun.com/to/m/5sing&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;全民K歌&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;a href=&#34;https://kytrun.com/to/m/qm&#34;&gt;https://kytrun.com/to/m/qm&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;</description>
    </item>
    <item>
      <title>一键打包下载 GitHub 仓库的 Issues</title>
      <link>https://kytrun.com/download-issues/</link>
      <pubDate>Fri, 13 Dec 2019 12:40:10 +0000</pubDate>
      <guid>https://kytrun.com/download-issues/</guid>
      <description>&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/1576212050601.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;写了个在线小工具一键下载-issues-为-markdown-文件的-zip-压缩包每个文件的标题为label-titlemd&#34;&gt;写了个在线小工具，一键下载 Issues 为 markdown 文件的 zip 压缩包，每个文件的标题为“label-title.md”。&lt;/h3&gt;
&lt;p&gt;以 &lt;a href=&#34;https://github.com/zhaopengme/gitnote/&#34;&gt;GitNote 的仓库&lt;/a&gt;为例&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/1576212064776.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;体验地址：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://git.io/gissue&#34;&gt;https://git.io/gissue&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Windows 映射 WebDAV 到本地</title>
      <link>https://kytrun.com/windows-webdav-to-local/</link>
      <pubDate>Fri, 13 Dec 2019 12:34:26 +0000</pubDate>
      <guid>https://kytrun.com/windows-webdav-to-local/</guid>
      <description>&lt;p&gt;新建一个 txt 文本，输入以下内容：保存后修改文件名后缀为 &lt;code&gt;.bat&lt;/code&gt;，(注意空格):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;net use Z: WebDAV地址 /user:你的账号 /persistent:YES 你的密码
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;（以上的 Z 指的是映射到本机地址作为虚拟的 Z 盘，可以改成其他的盘符，也可以用此方法建立多个，但尽量从字母表顺序往前倒着来，防止和已有的盘冲突）&lt;/p&gt;
&lt;p&gt;用坚果云举例，命名为 &lt;code&gt;WebDAVLink.bat&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;net use Z: https://dav.jianguoyun.com/dav /user:example@mail.com /persistent:YES mypassword
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;双击打开，效果：&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/1576211762029.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;然后将此文件 &lt;code&gt;WebDAVLink.bat&lt;/code&gt; 复制到以下路径，可以在系统启动时自动连接:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://gcore.jsdelivr.net/gh/kytrun/img/src/1576211749222.png&#34;&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
