Picocli之多级命令行参数解析
Posted 嗜血的羔羊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Picocli之多级命令行参数解析相关的知识,希望对你有一定的参考价值。
平时用Java写一些小工具,难免用到命令行参数解析,参数比较多的时候,再使用 args 一个个去判断就比较麻烦,且不优雅。
所以,使用现成的Picocli开源组件来实现。
下面记录的代码可以直接拿来用,以后就懒得写了。
0.效果
看看要达到的效果:
我们打包独立运行的 app.jar
,使用 java -jar app.jar 参数
运行。
我们的工具有多种功能,目前仅展示2个,所以我们不想直接就跟参数,想在中间插一级表示功能的命令:
# 导出
java -jar app.jar export -u xx -d xx ...
# 导入
java -jar app.jar import -u xx -d xx ...
完整的参数:
Usage: java -jar app.jar [-hV] [COMMAND]
-h, --help Show this help message and exit.
-V, --version Print version information and exit.
Commands:
export
import
Usage: java -jar app.jar export [-hV] [-d=<database>] -p=<secretKey>
-r=<jdbcUrl> [-t=<tables>] -u=<username>
-d, --database=<database> 库名,默认为default
-h, --help Show this help message and exit.
-p, --secret-key=<secretKey>
秘钥
-r, --jdbc-url=<jdbcUrl> 数据库地址
-t, --table=<tables> 表名,多个表用逗号分开
-u, --username=<username> 用户名
-V, --version Print version information and exit.
Usage: java -jar app.jar import [-hV] -f=<from> -p=<secretKey> -r=<jdbcUrl>
-t=<to> -u=<username>
-f, --from=<from> 来源
-h, --help Show this help message and exit.
-p, --secret-key=<secretKey>
秘钥
-r, --jdbc-url=<jdbcUrl> 数据库地址
-t, --to=<to> 目标
-u, --username=<username> 用户名
-V, --version Print version information and exit.
1.依赖
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>4.5.2</version>
</dependency>
2.实现代码
Picocli可以使用注解的方式代表参数类,我们采用注解。
我们首先定义父命令,使用 subcommands
表示子命令类。
@CommandLine.Command(
name = "java -jar app.jar",
subcommands = {ExportCmd.class, ImportCmd.class},
mixinStandardHelpOptions = true,
helpCommand = true)
public class CmdParam {
}
子命令类实现,就是最基础的Command
注解和Option
注解的使用。
@CommandLine.Command(name = "export", mixinStandardHelpOptions = true, helpCommand = true)
public class ExportCmd {
@CommandLine.Option(names = {"-r", "--jdbc-url"}, required = true, description = "数据库地址")
public String jdbcUrl;
@CommandLine.Option(names = {"-u", "--username"}, required = true, description = "用户名")
public String username;
@CommandLine.Option(names = {"-p", "--secret-key"}, required = true, description = "秘钥")
public String secretKey;
@CommandLine.Option(names = {"-d", "--database"}, defaultValue = "default", description = "库名,默认为default")
public String database;
@CommandLine.Option(names = {"-t", "--table"}, description = "表名,多个表用逗号分开")
public String tables;
}
@CommandLine.Command(name = "import", mixinStandardHelpOptions = true, helpCommand = true)
public class ImportCmd {
@CommandLine.Option(names = {"-r", "--jdbc-url"}, required = true, description = "数据库地址")
public String jdbcUrl;
@CommandLine.Option(names = {"-u", "--username"}, required = true, description = "用户名")
public String username;
@CommandLine.Option(names = {"-p", "--secret-key"}, required = true, description = "秘钥")
public String secretKey;
@CommandLine.Option(names = {"-f", "--from"}, required = true, description = "来源")
public String from;
@CommandLine.Option(names = {"-t", "--to"}, required = true, description = "目标")
public String to;
}
但是,这还没完,我们再main
方法的入口进行解析。
当解析错误、或者参数为空时,我们打印help
结果,包括父子命令。
public static void main(String[] args) {
// 解析参数
final CmdParam cmdParam = new CmdParam();
final CommandLine commandLine = new CommandLine(cmdParam);
try {
final CommandLine.ParseResult parseResult = commandLine.parseArgs(args);
checkParamHelp(args.length == 0, commandLine, parseResult);
if (parseResult.hasSubcommand()) {
for (CommandLine.ParseResult subCommand : parseResult.subcommands()) {
final CommandLine c = subCommand.commandSpec().commandLine();
checkParamHelp(args.length == 1, c, subCommand);
}
}
} catch (CommandLine.ParameterException e) {
commandLine.usage(System.out);
for (CommandLine c : commandLine.getSubcommands().values()) {
c.usage(System.out);
}
System.exit(1);
}
log.info("cmd params:{}", cmdParam);
}
private static void checkParamHelp(boolean empty, CommandLine commandLine, CommandLine.ParseResult parseResult) {
if (empty || parseResult.isUsageHelpRequested()) {
commandLine.usage(System.out);
System.exit(0);
}
if (parseResult.isVersionHelpRequested()) {
commandLine.printVersionHelp(System.out);
System.exit(0);
}
}
最后打包成一个可执行jar包就大功告成了。
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.jimo.tool.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
以上是关于Picocli之多级命令行参数解析的主要内容,如果未能解决你的问题,请参考以下文章