做网站会提供源代码吗,VPS wordpress 教程,网络营销上的网站建设流程,网站建设饱和了吗大家好#xff0c;我是鱼皮#xff0c;对不会前端的同学来说#xff0c;开发 命令行工具 是一种不错的展示系统功能的方式。在 Java 中开发命令行工具也很简单#xff0c;使用框架#xff0c;几分钟就能学会啦~ Picocli 入门 Picocli 是 Java 中个人认为功能最完善、最简单… 大家好我是鱼皮对不会前端的同学来说开发 命令行工具 是一种不错的展示系统功能的方式。在 Java 中开发命令行工具也很简单使用框架几分钟就能学会啦~ Picocli 入门 Picocli 是 Java 中个人认为功能最完善、最简单易用的命令行开发框架可以帮助大家快速开发命令行工具。 网上有关 Picocli 框架的教程非常少最推荐的入门方式除了看鱼皮的教程外就是阅读官方文档了。 官方文档https://picocli.info/ 推荐从官方提供的快速入门教程开始https://picocli.info/quick-guide.html 一般我们学习新技术的步骤是先跑通入门 Demo再学习该技术的用法和特性。 入门 Demo 1在 Maven 项目的 pom.xml 文件中引入 picocli 的依赖 !-- https://picocli.info --dependency groupIdinfo.picocli/groupId artifactIdpicocli/artifactId version4.7.5/version/dependency 然后我们在 com.yupi 包下新建 cli.example 包用于存放所有和 Picocli 入门有关的示例代码。 2复制官方快速入门教程中的示例代码到 com.yupi.cli.example 包下并略微修改 run 方法中的代码打印参数的值。 完整代码如下 package com.yupi.cli.example;import picocli.CommandLine;import picocli.CommandLine.Command;import picocli.CommandLine.Option;import picocli.CommandLine.Parameters;Command(name ASCIIArt, version ASCIIArt 1.0, mixinStandardHelpOptions true) public class ASCIIArt implements Runnable { Option(names { -s, --font-size }, description Font size) int fontSize 19; Parameters(paramLabel word, defaultValue Hello, picocli, description Words to be translated into ASCII art.) private String[] words { Hello,, picocli }; Override public void run() { // 自己实现业务逻辑 System.out.println(fontSize fontSize); System.out.println(words String.join(,, words)); } public static void main(String[] args) { int exitCode new CommandLine(new ASCIIArt()).execute(args); System.exit(exitCode); }} 看不懂这段代码没关系官方文档已经给了非常详细的解释 帮大家翻译一下 创建一个实现 Runnable 或 Callable 接口的类这就是一个命令。 使用 Command 注解标记该类并为其命名 mixinStandardHelpOptions 属性设置为 true 可以给应用程序自动添加 --help 和 --version 选项。 通过 Option 注解将字段设置为命令行选项可以给选项设置名称和描述。 通过 Parameters 注解将字段设置为命令行参数可以指定默认值、描述等信息。 Picocli 会将命令行参数转换为强类型值并自动注入到注解字段中。 在类的 run 或 call 方法中定义业务逻辑当命令解析成功用户敲了回车后被调用。 在 main 方法中通过 CommandLine 对象的 execute 方法来处理用户输入的命令剩下的就交给 Picocli 框架来解析命令并执行业务逻辑啦~ CommandLine.execute 方法返回一个退出代码。可以调用 System.exit 并将该退出代码作为参数从而向调用进程表示成功或失败。 3让我们更改主程序的执行参数args来测试程序能够成功看到输出结果如下图 通过这个入门 Demo我们可以简单总结一个命令的开发流程 创建命令 设置选项和参数 编写命令执行的业务逻辑 通过 CommandLine 对象接受输入并执行命令 在跑通了入门 Demo 后我们来学习一些 Picocli 开发命令行的实用功能。 实用功能 1、帮助手册 通过给类添加的 Command 注解参数 mixinStandardHelpOptions 设置为 true 来开启 Command(name ASCIIArt, mixinStandardHelpOptions true) 然后将主程序的输入参数设置为 --help 就能打印出命令的帮助手册信息了如下图 可以看到Picocli 生成的帮助手册不仅规范、而且清晰完整。 2、命令解析 Picocli 最核心的能力就是命令解析能够从一句完整的命令中解析选项和参数并填充到对象的属性中。 Picocli 使用注解的方式实现命令解析不需要自己编写代码整个类看起来非常清晰。 最核心的 2 个注解其实在入门 Demo 中我们已经使用到了 Option 注解用于解析选项 Parameters 注解用于解析参数 示例代码如下 Option(names { -s, --font-size }, description Font size) int fontSize 19;Parameters(paramLabel word, defaultValue Hello, picocli, description Words to be translated into ASCII art.)private String[] words { Hello,, picocli }; 可以给这些注解指定参数比较常用的参数有 1Option 注解的 names 参数指定选项英文名称。 2description 参数指定描述信息从而让生成的帮助手册和提示信息更清晰。 3Parameters 注解的 paramLabel 参数参数标签作用类似于描述信息。 4Parameters 注解的 defaultValue 参数默认值参考文档https://picocli.info/#_default_values 5required 参数要求必填参考文档https://picocli.info/#_required_arguments 示例代码如下 class RequiredOption { Option(names -a, required true) String author;} 此外命令解析天然支持 多值选项只需要把对象属性的类型设置为数组类型即可比如 Option(names -option)int[] values; 具体可以参考官方文档https://picocli.info/#_multiple_values 更多关于选项和参数注解的用法也可以阅读官方文档学习https://picocli.info/quick-guide.html#_options_and_parameters 3、交互式输入 所谓的交互式输入就是允许用户像跟程序聊天一样在程序的指引下一个参数一个参数地输入。 如下图 Picocli 为交互式输入提供了很好的支持我梳理了大概 4 种交互式输入的模式。 1基本能力 交互式输入的一个典型应用场景就是用户要登录时引导 ta 输入密码。 官方已经为我们提供了一段交互式输入的示例代码鱼皮对它进行了简化示例代码如下 参考官方文档https://picocli.info/#_interactive_password_options package com.yupi.cli.example;import picocli.CommandLine;import picocli.CommandLine.Option;import java.util.concurrent.Callable;public class Login implements CallableInteger { Option(names {-u, --user}, description User name) String user; Option(names {-p, --password}, description Passphrase, interactive true) String password; public Integer call() throws Exception { System.out.println(password password); return 0; } public static void main(String[] args) { new CommandLine(new Login()).execute(-u, user123, -p); }} 让我们分析下上面的代码主要包含 4 个部分 1首先命令类需要实现 Callable 接口 public class Login implements CallableInteger { ...} 2将 Option 注解的 interactive 参数设置为 true表示该选项支持交互式输入 Option(names {-p, --password}, interactive true)String password; 3在所有参数都输入完成后会执行 call 方法可以在该方法中编写具体的业务逻辑 public Integer call() throws Exception { System.out.println(password password); return 0;} 4在 Main 方法中执行命令并传入参数 new CommandLine(new Login()).execute(-u, user123, -p); 执行上述代码看到程序提示我们输入密码 注意如果以 jar 包方式运行上述程序用户的输入默认是不会显示在控制台的类似输入密码时的体验。从 Picocli 4.6 版本开始可以通过指定 Option 注解的 echo 参数为 true 来显示用户的输入并通过 prompt 参数指定引导用户输入的提示语。 2多个选项交互式 Picocli 支持在一个命令中指定多个交互式输入的选项会按照顺序提示用户并接收输入。 在上述代码中再增加一个 checkPassword 选项同样开启交互式输入代码如下 public class Login implements CallableInteger { Option(names {-u, --user}, description User name) String user; Option(names {-p, --password}, description Passphrase, interactive true) String password; Option(names {-cp, --checkPassword}, description Check Password, interactive true) String checkPassword; public Integer call() throws Exception { System.out.println(password password); System.out.println(checkPassword checkPassword); return 0; } public static void main(String[] args) { new CommandLine(new Login()).execute(-u, user123, -p); }} 但运行上述代码我们会发现怎么只提示我输入了密码没提示我输入确认密码呢 这是由于 Picocli 框架的规则用户必须在命令中指定需要交互式输入的选项比如 -p才会引导用户输入。 所以我们需要修改上述代码中的 main 方法给命令输入补充 -cp 参数 public static void main(String[] args) { new CommandLine(new Login()).execute(-u, user123, -p, -cp);} 再次执行这下程序会依次提醒我们输入两个选项啦 根据实际使用情况又可以将交互式输入分为 2 种模式 可选交互式用户可以直接在整行命令中输入选项而不用给用户提示信息。 强制交互式用户必须获得提示并输入某个选项不允许不填写。 下面分别讲解这两种模式。 3可选交互式 默认情况下是无法直接在命令中给交互式选项指定任何参数的只能通过交互式输入比如命令中包含 -p xxx 会报错。 可选交互式官方文档https://picocli.info/#_optionally_interactive 让我们测试一下给上面的示例代码输入以下参数 new CommandLine(new Login()).execute(-u, user123, -p, xxx, -cp); 执行效果如下图出现了参数不匹配的报错 官方提供了可选交互式的解决方案通过调整 Option 注解中的 arity 属性来指定每个选项可接受的参数个数就能解决这个问题。 arity 官方介绍https://picocli.info/#_arity 示例代码如下 Option(names {-p, --password}, arity 0..1, description Passphrase, interactive true)String password; 然后可以直接在完整命令中给交互式选项设置值 new CommandLine(new Login()).execute(-u, user123, -p, 123, -cp); 执行结果如图不再提示让用户输入 password 选项而是直接读取了命令中的值 这里鱼皮推荐一个最佳实践建议给所有需要交互式输入的选项都增加 arity 参数一般是 arity 0..1这样用户既可以在完整命令中直接给选项填充参数也可以选择交互式输入。 示例代码如下 public class Login implements CallableInteger { Option(names {-u, --user}, description User name) String user; // 设置了 arity 参数可选交互式 Option(names {-p, --password}, arity 0..1, description Passphrase, interactive true) String password; // 设置了 arity 参数可选交互式 Option(names {-cp, --checkPassword}, arity 0..1, description Check Password, interactive true) String checkPassword; public Integer call() throws Exception { System.out.println(password password); System.out.println(checkPassword checkPassword); return 0; } public static void main(String[] args) { new CommandLine(new Login()).execute(-u, user123, -p, 123, -cp, 456); }} 4强制交互式 在之前已经提到如果用户不在命令中输入交互式选项比如 -p那么系统不会提示用户输入这个选项属性的值将为默认值比如 null。 举个例子下列命令中不带 -p 选项 new CommandLine(new Login()).execute(-u, user123); 执行就会发现程序不会提示用户输入 -p 选项的参数而是直接输出结果值为 null 但有些时候我们要求用户必须输入某个选项而不能使用默认的空值怎么办呢 官方给出了强制交互式的解决方案参考文档https://picocli.info/#_forcing_interactive_input 但是官方的解决方案是需要自己定义业务逻辑的。原理是在命令执行后对属性进行判断如果用户没有输入指定的参数那么再通过 System.console().readLine 等方式提示用户输入示例代码如下 Commandpublic class Main implements Runnable { Option(names --interactive, interactive true) String value; public void run() { if (value null System.console() ! null) { // 主动提示用户输入 value System.console().readLine(Enter value for --interactive: ); } System.out.println(You provided value value ); } public static void main(String[] args) { new CommandLine(new Main()).execute(args); }} 个人不是很喜欢这种方案因为要额外编写提示代码感觉又回到自主实现了。 鱼皮想出的一种方案是编写一段通用的校验程序如果用户的输入命令中没有包含交互式选项那么就自动为输入命令补充该选项即可这样就能强制触发交互式输入。 说通俗一点检测 args 数组中是否存在对应选项不存在则为数组增加选项元素。 该思路作为一个小扩展点实现起来并不复杂大家可以自行实现。小提示可以利用反射自动读取必填的选项名称 4、子命令 子命令是指命令中又包含一组命令相当于命令的分组嵌套适用于功能较多、较为复杂的命令行程序比如 git、docker 命令等。 官方文档https://picocli.info/#_subcommands 在 Picocli 中提供了两种设置子命令的方式。 1声明式 通过 Command 注解的 subcommands 属性来给命令添加子命令优点是更直观清晰。 示例代码如下 Command(subcommands { GitStatus.class, GitCommit.class, GitAdd.class, GitBranch.class, GitCheckout.class, GitClone.class, GitDiff.class, GitMerge.class, GitPush.class, GitRebase.class, GitTag.class})public class Git { /* ... */ } 2编程式 在创建 CommandLine 对象时调用 addSubcommand 方法来绑定子命令优点是更灵活。 示例代码如下 CommandLine commandLine new CommandLine(new Git()) .addSubcommand(status, new GitStatus()) .addSubcommand(commit, new GitCommit()) .addSubcommand(add, new GitAdd()) .addSubcommand(branch, new GitBranch()) .addSubcommand(checkout, new GitCheckout()) .addSubcommand(clone, new GitClone()) .addSubcommand(diff, new GitDiff()) .addSubcommand(merge, new GitMerge()) .addSubcommand(push, new GitPush()) .addSubcommand(rebase, new GitRebase()) .addSubcommand(tag, new GitTag()); 实践 让我们编写一个示例程序支持增加、删除、查询 3 个子命令并传入不同的 args 来测试效果。 完整代码如下 package com.yupi.cli.example;import picocli.CommandLine;import picocli.CommandLine.Command;Command(name main, mixinStandardHelpOptions true)public class SubCommandExample implements Runnable { Override public void run() { System.out.println(执行主命令); } Command(name add, description 增加, mixinStandardHelpOptions true) static class AddCommand implements Runnable { public void run() { System.out.println(执行增加命令); } } Command(name delete, description 删除, mixinStandardHelpOptions true) static class DeleteCommand implements Runnable { public void run() { System.out.println(执行删除命令); } } Command(name query, description 查询, mixinStandardHelpOptions true) static class QueryCommand implements Runnable { public void run() { System.out.println(执行查询命令); } } public static void main(String[] args) { // 执行主命令 String[] myArgs new String[] { }; // 查看主命令的帮助手册// String[] myArgs new String[] { --help }; // 执行增加命令// String[] myArgs new String[] { add }; // 执行增加命令的帮助手册// String[] myArgs new String[] { add, --help }; // 执行不存在的命令会报错// String[] myArgs new String[] { update }; int exitCode new CommandLine(new SubCommandExample()) .addSubcommand(new AddCommand()) .addSubcommand(new DeleteCommand()) .addSubcommand(new QueryCommand()) .execute(myArgs); System.exit(exitCode); }} 测试运行发现当输入 --help 参数时打印出了主命令和所有的子命令信息证明子命令绑定成功 实践 编程导航星球的定制化代码生成项目就是使用了 Picocli 来开发命令行应用。 编程导航原创项目教程系列https://yuyuanweb.feishu.cn/wiki/SePYwTc9tipQiCktw7Uc7kujnCd OK 就到这里创作不易学会的同学点个赞吧~