首先使用 nvm ls 列出当前安装的所有版本。 然后使用 nvm use 14.17.0 来选择不同的版本。 nvm use 后面跟的是版本号。 当切换完成后,可以使用 node -v 来查看重新定义的版本。 https://www.ossez.com/t/nvm/13729
首先使用 nvm ls 列出当前安装的所有版本。 然后使用 nvm use 14.17.0 来选择不同的版本。 nvm use 后面跟的是版本号。 当切换完成后,可以使用 node -v 来查看重新定义的版本。 https://www.ossez.com/t/nvm/13729
完整的错误信息为: 14 verbose stack Error: Unsupported URL Type "npm:": npm:@elastic/elasticsearch@7.13.0 14 verbose stack at unsupportedURLType (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\npm-package-arg\npa.js:197:15) 14 verbose stack at fromURL (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\npm-package-arg\npa.js:250:13) 14 verbose stack at Function.resolve (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\npm-package-arg\npa.js:71:12) 14 verbose stack at module.exports (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\lib\install\realize-shrinkwrap-specifier.js:21:14) 14 verbose stack at BB.each (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\lib\install\inflate-shrinkwrap.js:51:23) 14 verbose stack at tryCatcher (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\bluebird\js\release\util.js:16:23) 14 verbose stack at Object.gotValue (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\bluebird\js\release\reduce.js:155:18) 14 verbose stack at Object.gotAccum (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\bluebird\js\release\reduce.js:144:25) 14 verbose stack at Object.tryCatcher (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\bluebird\js\release\util.js:16:23) 14 verbose stack at Promise._settlePromiseFromHandler (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\bluebird\js\release\promise.js:512:31) 14 verbose stack at Promise._settlePromise (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\bluebird\js\release\promise.js:569:18) 14 verbose stack at Promise._settlePromise0 (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\bluebird\js\release\promise.js:614:10) 14 verbose stack at Promise._settlePromises (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\bluebird\js\release\promise.js:693:18) 14 verbose stack at Async._drainQueue (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\bluebird\js\release\async.js:133:16) 14 verbose stack at Async._drainQueues (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\bluebird\js\release\async.js:143:10) 14 verbose stack at Immediate.Async.drainQueues (C:\Users\huyuc\AppData\Roaming\nvm\v8.9.4\node_modules\npm\node_modules\bluebird\js\release\async.js:17:14) 15 verbose cwd D:\WorkDir\FacilityConneX\Source-Code\Services\API 16 verbose Windows_NT 10.0.19043 17 verbose argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install" "--frozen-lockfile" 18 verbose node v8.9.4 19 verbose npm v5.6.0 20 error code EUNSUPPORTEDPROTOCOL 21 error Unsupported URL Type "npm:": npm:@elastic/elasticsearch@7.13.0 22 verbose exit [ 1, true ] 从上面的错误信息我们来抓重点看就是第一行 verbose stack Error: Unsupported URL Type "npm:": npm:@elastic/elasticsearch@7.13.0 Unsupported URL Type 这个错误。 错误原因和解决 出现这个错误的原因是你的 node 版本可能过低了。 你需要切换使用更高一点的 node 版本。 如果你对切换 node 的版本和 NPM 之间的关系有什么不清楚的话,可以参考下面的内容:NPM 和 NVM 当你切换 node 版本完成后,再次尝试安装就应该能够解决你的这个问题了。 当我们切换版本完成后再次进行安装,就能够成功了。 https://www.ossez.com/t/npm-eunsupportedprotocol/13728
在写代码的时候,我们会经常会对数组或者集合进行一些遍历。 聪明的你肯定想快速插入类似下面的代码,定义一个 int i ,然后 i 从 0 开始对集合进行遍历。 for (int i = 0; i < testList.size(); i++) { } IntelliJ IDEA 的 fori 解决办法 在空白处,直接输入 for 在你输入 for 以后,你应该能够看到下面的小窗口。 在上面的小窗口中,选择 fori,随后你的 IntelliJ IDEA 将会自动为你插入下面的代码。 for (int i = 0; i < ; i++) { } 使用上面的代码,你就不用再敲打一次 int i 这种定义了。 能够帮忙你解决定义整型的麻烦。 IntelliJ IDEA 的 foreach 解决办法 我们知道 Java 在 JDK 5 以后的循环还有另外一种写法。 在这里,你可以使用 foreach 解决办法。 上面 foreach 的解决办法将会帮你插入: for (: ) { } 这个语句。 然后你就可以在上面的语句中直接对集合进行遍历了。 总结 使用 IntelliJ IDEA 的快捷键和语法提示能够帮我们提高编码效率。 对集合进行遍历或者查找是程序中经常用到的方法,希望上面的这个小技巧能够帮忙少敲几个变量定义。 https://www.ossez.com/t/intellij-idea-for/13726
Java 的 List 遍历通常会使用迭代器(Iterator)来进行遍历 Iterator 与 Iterable Iterator 为 Java中的迭代器对象,是能够对 List 这样的集合进行迭代遍历的底层依赖。而 Iterable 接口里定义了返回 Iterator 的方法,相当于对 Iterator 的封装,同时实现了Iterable 接口的类可以支持 for each循环。 Java 遍历集合的演进 Java 最开始设计的时候都会使用迭代器来对集合进行遍历。 类似下面的写法是不是非常熟悉,在定义集合后,然后使用迭代器,然后使用迭代器中的 hasNext() 方法来完成遍历。 List<String> testList = Arrays.asList("A", "B", "C"); Iterator iterator = testList.iterator(); while (iterator.hasNext()) { logger.debug((String) iterator.next()); } 上面的代码运行后,我们会知道输出应该为:A,B,C 使用 for 循环 因为上面的方法有时候会出点问题,比如说空对象异常呀。 或者通常没有办法获得当前遍历的下标等等。 然后就有很多人会开始使用一个 for 循环。 List<String> testList = Arrays.asList("A", "B", "C"); logger.debug("--- FOR ---"); for (int i = 0; i < testList.size(); i++) { logger.debug("{} > {}", i, testList.get(i)); } 当你运行上面的代码后,控制台的输出应该为: 15:38:55.241 [main] DEBUG com.ossez.java8.Java8ForEachUnitTest - --- FOR --- 15:38:55.241 [main] DEBUG com.ossez.java8.Java8ForEachUnitTest - 0 > A 15:38:55.242 [main] DEBUG com.ossez.java8.Java8ForEachUnitTest - 1 > B 15:38:55.242 [main] DEBUG com.ossez.java8.Java8ForEachUnitTest - 2 > C 需要记住的是,Java 中 List 的下标是从 0 开始的。 然后就有点郁闷了,有时候我们会对 List 遍历个多次,然后每次都 i 的话,经常都不知道 i 到最后的 i 的值是多少了。 更有可能的是,一些可爱的代码会用到 i,j ,k,m,n 运气不好会看到好几个。 for 的另外一种写法 针对上面的情况,如果你只是需要遍历的话,你还是可以考虑这样写。 List<String> testList = Arrays.asList("A", "B", "C"); logger.debug("--- FOR LOOP ---"); for (String s : testList) { logger.debug(s); } 如果需要下标的话,还是可以在里面直接定义一个 i 进行一些操作的。 在 JDK 5 以后的版本中,这种写法越来越多了,通常直接定义 i 的循环就比较少了。 上面的这个代码的可读性就更强一些了。 forEach 这个在 JDK 8 以后就可以这样写了。 List<String> testList = Arrays.asList("A", "B", "C"); logger.debug("--- FOR EACH ---"); testList.forEach(s -> { logger.debug(s); }); 这个是使用的 lambda 表达式的的循环,有点装逼的写法。 基本上和上面 for 的第二种写法差不多,如果你的集合实现了 Iterable 接口的话,通常就可以这样写了。 如果你能读读 JDK 源代码的话,就知道 Iterable 对迭代器进行了封装。 forEach 比直接 for 要高端一点点。 总结 不管采用什么样的写法,第一种直接迭代的写法是比较少见的。 通常不使用迭代器直接写的原因是集合不好操作。 Java 的遍历方式也越来越方便了,具体希望怎么遍历还是通过具体问题具体分析。掌握 1 到 2 种遍历方式基本上也够用了。 https://www.ossez.com/t/java-8-foreach/13725
概述 本快速指南的主要目的是如何使用 Jackson 2 来将一个字符串转换为 JsonNode 对象。 JsonNode 定义在 com.fasterxml.jackson.databind.JsonNode 包中。 快速转换 可以使用下面的代码直接进行转换。 转换的方式也比较简单,在定义好 ObjectMapper 对象后,直接使用这个对象的 readTree 方法将输入的字符串转换为 JsonNode 对象。 考察下面的代码: @Test public void whenParsingJsonStringIntoJsonNode_thenCorrect() throws JsonParseException, IOException { String jsonString = "{"k1":"v1","k2":"v2"}"; ObjectMapper mapper = new ObjectMapper(); JsonNode actualObj = mapper.readTree(jsonString); assertNotNull(actualObj); } 低级别的转换 在有些情况下,你可能需要使用更加低级别的转换,比如说在转换的时候需要对一些输出参数进行设置。 那么你就需要先配置 Parser 了。 与前面的快速转换不同的是,在你 new 了一个新的 ObjectMapper 对象后,你需要从这个对象中获得 Factory。 然后再创建一个 Parser,最后再调用 readTree 的方法。 请考察下面的代码: @Test public void givenUsingLowLevelApi_whenParsingJsonStringIntoJsonNode_thenCorrect() throws JsonParseException, IOException { String jsonString = "{"k1":"v1","k2":"v2"}"; ObjectMapper mapper = new ObjectMapper(); JsonFactory factory = mapper.getFactory(); JsonParser parser = factory.createParser(jsonString); JsonNode actualObj = mapper.readTree(parser); assertNotNull(actualObj); } JsonNode 的使用 当 JSON 字符串被处理成了 JsonNode 对象后,那我们可以使用 JSON Tree Model 来对转换后的 JSON 对象进行操作。 例如下面的代码,首先我们完成了字符串到 JSON 对象的转换,然后转换完成后,我们通过 K1 的对定义来获得值。 @Test public void givenTheJsonNode_whenRetrievingDataFromId_thenCorrect() throws JsonParseException, IOException { String jsonString = "{"k1":"v1","k2":"v2"}"; ObjectMapper mapper = new ObjectMapper(); JsonNode actualObj = mapper.readTree(jsonString); // When JsonNode jsonNode1 = actualObj.get("k1"); assertThat(jsonNode1.textValue(), equalTo("v1")); } 结论 在使用 fasterxml 的 jackson 包对 Json 数据操作之前,首先需要做的事情就是将输入的 String 或者文件或者不同的输入流转换为 JsonNode 对象。 后续的操作就是对 JsonNode 的对象进行操作了。 例如,上面我们的一个 JsonNode 对象是一个数组,那么我们可以对上面的数组中转换后的对象进行遍历。 https://www.ossez.com/t/jackson-jsonnode/13724
如果你参考了 GitHub 上的安装指南 页面中的内容安装了一个 Discourse 实例后希望对自己安装的实例修改域名的使用手册。 如果你使用的是 Discourse 官方主机服务 的话,请参考 针对 Discourse 的云服务配置你的域名 页面中的详细内容。 假设,你现在希望修改你的 Discourse 实例的 域名从 talk.foo.com → talk.bar.com。 让我们开始这个过程吧。 在 DNS 的高级设置中,设置 TTL 为 low(低) 你希望让所有人都知道你的域名被修改了,因此你可以在你的域名 DNS 中设置 TTL 时间为低,例如可以设置为 60 分钟。 这个设置的主要目的是能够让你的 DNS 修改更快的生效。互联网中 DNS 的修改是需要时间的,因为有缓存的存在。 从站点中删除所有有关老的域名配置 访问 /admin/site_settings 然后搜索所有有关老的域名的配置。 如果你的搜索中找到了一些有关老的域名的配置,请确定你将上面的配置进行修改。 在 app.yml 文件中编辑 Discourse 的配置 可选的,你可以再次运行 ./discourse-setup 命令,然后通过这个命令提示的输入信息将新的域名更新到 app.yml 配置文件中。 在 app.yml 文件中,编辑 hostname 的内容。 ## Discourse 实例中的主机名将会被修改为如下 DISCOURSE_HOSTNAME: 'talk.bar.com' (同时,如果你还使用了 CDN 的话,你可以在 app.yml 文件中,将有关 CDN 的配置进行注释掉。在完成修改后,再将注释取消就可以了。) 在完成上面的配置后,需要对 Discourse 进行重构: ./launcher rebuild app 当你完成上面的重构后,你的站点只能通过新的域名来访问了。 修改你的 DNS 配置 将老的域名的 DNS 记录删除 修改新域名的 DNS 记录,将记录指向到你的 Discourse 服务地址。 当完成上面的配置后,你应该是没有问题通过新修改的域名来访问你的 Discourse 站点的。 你也可以同时在站点进行重构的时候修改你的 DNS 配置信息。 校验所有功能都能够正常访问,在我们对功能进行校验的时候,我们希望先确定我们能够正常登录我们的 Discourse 系统。这个就是下面的主题需要解决的问题… 修改第三方登录 基于你如何进行登录的方式不同,你需要马上对这个进行修改,否则你在域名修改完成后就没有办法通过第三方进行登录了。 你的 Twitter, Facebook, Google, Yahoo, GitHub 社交媒体账号登录配置中同时也需要修改来让回调地址和你新修改的地址一致。 请参考官方的相关文章来进行配置和修改。 将主题中所有有关老站点的引用替换为新站点的域名 现在所有主题和帖子中有关站点主题的链接都还是老的域名的,我们现在需要修改这个,帖子中的链接指向新的域名。让我们来进行操作: BEFORE AFTER ./launcher enter app 然后输入并且输入下面的命令: discourse remap talk.foo.com talk.bar.com 根据提示的内容进行修改后,再执行下面的命令: rake posts:rebake 主题中的 remaps 现在将会使用新的域名地址替换为老的域名地址,然后我们重新生成了所有的主题,以避免有所遗漏。 至此,所有修改域名的配置都已经完成了! (如果开始你注释掉了 CDN 的配置信息的话,不要忘记将上面的修改改回来。) 想知道 在主题中的输入对话框是如何创建的吗? https://www.ossez.com/t/discourse/13717/2
如下图显示的内容,可以在输入框中输入文本,然后在主题中可以根据你输入的文本重新生成字符串: 效果演示 请在下面的输入框中输入文本,然后观察输出的变化 ZNAME在邮件列表中使用的名字 ZCOUNTRYFRDEUSCNAUCA 你的邮件地址: =ZNAME=-US@example.com 需要的插件 如果需要在你的 Discourse 安装中使用这个功能,你需要使用 discourse-placeholder-theme-component 这个仓库。 单击下面的链接来访问这个仓库。 仓库链接 如何安装 访问你的管理员控制台界面。 然后选择主题的组件,单击 安装按钮。 在弹出的对话框中输入 Git 的仓库地址。 根据官方的仓库,我们 fork 了一个,GitHub - ossez-com/discourse-placeholder-theme-component: discourse-placeholder-theme-component 在这个仓库中在,主要是添加了简体中文的语言文件。 当安装成功后,你就可以看到下面的界面了。 需要注意的是,在配置的界面中,需要将主题选择上。 如果你不选择主题的话,那么你的这个插件就没有办法使用。 根据 Discourse 的设计逻辑,主题下面是组件,我们现在安装的是组件,在组件安装完成后需要和主题进行关联。 因此如果你不选择的话,或者选择部分的话,那么用户在切换主题的时候,可能这个组件就不能用了。 https://www.ossez.com/t/discourse/13720
也不知道 Confluence 的官方是怎么想的。 Confluence 的数据中心支持在 2024年2月2号停止技术支持,所有的服务都会使用云服务。 这个无异于是自杀类型的举动,很多公司的数据是非常敏感的是没有办法上云的,不知道他们是不是脑袋被驴踢了? 估计不少公司又要开始找下家了。 https://www.ossez.com/t/confluence/13716
在新的 RedHat 8 或者更新的 Linux 版本中,我们可以使用 timedatectl 来对时间进行相关的操作进行一些修改。 设置时区 当系统完成初始化以后,对时间的设置是非常必要的,可以使用下面的方法对时区进行修改。 例如,如果你希望修改时区为美国东部时间的话,直接运行下面的命令: timedatectl set-timezone America/New_York 就可以了。 设置 NTP 同步 以前,我们还需要装一大堆的 NTP 服务来对时间进行同步。 现在只需要运行: timedatectl set-ntp yes 就可以设置自动同步了。 是不是非常方便了。 总结 可以只运行 2 句话解决时间同步和时区的问题。 [root@monitor ~]# timedatectl set-timezone America/New_York [root@monitor ~]# timedatectl set-ntp yes 运行下下面的命令查看下状态吧。 [root@monitor ~]# timedatectl status Local time: Thu 2021-09-02 15:39:12 EDT Universal time: Thu 2021-09-02 19:39:12 UTC RTC time: Thu 2021-09-02 19:39:12 Time zone: America/New_York (EDT, -0400) NTP enabled: yes NTP synchronized: yes RTC in local TZ: no DST active: yes Last DST change: DST began at Sun 2021-03-14 01:59:59 EST Sun 2021-03-14 03:00:00 EDT Next DST change: DST ends (the clock jumps one hour backwards) at Sun 2021-11-07 01:59:59 EDT Sun 2021-11-07 01:00:00 EST [root@monitor ~]# 查看下当前的状态,是不是越来越方便了。 https://www.ossez.com/t/redhat-8/13714
在 Linux 调试的时候非常麻烦的就是检查端口是否联通。 其中可能有各种原因导致端口没有联通,通常为操作系统本身的防火墙,托管服务器中心的防火墙等。 因为网络不通,导致各种问题的出现。 nc 也被称为 netcat 就是你的好朋友了。 安装 运行下面的命令就可以进行安装了,如果你的 dnf 不能使用,那么试下 yum dnf install nc Linux 的 nc 命令用于设置路由器。 执行本指令可设置路由器的相关参数。 执行命令检查端口 可以直接执行下面的命令,来检查特定地址的特定端口是否是开放的。 nc -z -v 127.0.0.1 10050 上面的命令查看 IP 地址为:127.0.0.1 端口为:10050 如果出现下面的返回,则表明端口是联通的。 [root@monitor ~]# nc -z -v 127.0.0.1 10050 Ncat: Version 7.50 ( https://nmap.org/ncat ) Ncat: Connected to 127.0.0.1:10050. Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds. [root@monitor ~]# 如果你需要查看远程服务器的特定端口的话,修改不同的地址就行。 总结 需要注意的是,IP 地址和端口直接使用空格分开。 -z 使用 0 输入/输出模式,只在扫描通信端口时使用。 -v 显示指令执行过程。 如果你还需要了解其他参数,请参考相关手册。 https://www.ossez.com/t/redhat-8/13713