命令行参数解析picocli快速使用

关于命令行参数解析的库还挺多,调研之后选择了 picocli 这个库

因为其文档很全,所以下面是一个快速使用的教程,抓住主干再揪细节。

        <dependency>
            <groupId>info.picocli</groupId>
            <artifactId>picocli</artifactId>
            <version>4.5.2</version>
        </dependency>

效果

先看看,再实现

$ java -jar cli.jar -h
Usage: java -jar cli.jar [-hV] -p=<secret> -u=<user> [-c=<String=String>]...
                       -s=<servers>[,<servers>...] [-s=<servers>[,
                       <servers>...]]...
  -c, --config=<String=String>
                             -c k1=v1 -c k2=v2
  -h, --help                Show this help message and exit.
  -p, --password=<secret>   login secret or password
  -s, --server=<servers>[,<servers>...]
                             servers,split by comma: host1:port1,host2:
                              port2
  -u, --user=<user>         login username
  -V, --version             Print version information and exit.

定义参数类

使用注解来定义参数类

一般只需要2个注解即可搞定:

  • @CommandLine.Command: 定义在类上,声明应用执行名字,版本等
  • @CommandLine.Option: 用在属性上,代表参数

下面是一个示例:

import picocli.CommandLine;

import java.util.Map;

@CommandLine.Command(name = "java -jar cli.jar")
public class CliParam {

    @CommandLine.Option(names = {"-h", "--help"}, usageHelp = true, description = " cmd cli help msg")
    public boolean help = false;

    @CommandLine.Option(names = {"-s", "--server"}, required = true, split = ",", converter = ServerTypeConverter.class,
            description = " servers,split by comma: host1:port1,host2:port2 ")
    public String[] servers;

    @CommandLine.Option(names = {"-u", "--user"}, required = true, description = "login username")
    public String user;

    @CommandLine.Option(names = {"-p", "--password"}, required = true,
            description = "login secret or password")
    public String secret;

    /**
     * 一些额外的参数
     */
    @CommandLine.Option(names = {"-c", "--config"}, description = " -c k1=v1 -c k2=v2")
    public Map<String, String> configs;

    static class ServerTypeConverter implements CommandLine.ITypeConverter<String> {

        @Override
        public String convert(String s) {
            final String[] hp = s.split(":");
            if (hp.length != 2) {
                throw new CommandLine.TypeConversionException("Invalid servers, must be: host1:port1,host2:port2," +
                        " but was:'" + s + "'");
            }
            String host = hp[0].trim();
            int port = Integer.parseInt(hp[1].trim());
            return host + (port == 80 ? "" : ":" + port);
        }
    }
}

其中ServerTypeConverter可以自定义解析,这里接收一个逗号分割的字符串,返回一个数组。

声明版本

可以直接写死,也可以动态加载

@CommandLine.Command(name = "java -jar cli.jar",
					versionProvider = CliParam.MyVersionProvider.class)
public class CliParam {

    /**
     * 动态获取版本号,从内部配置里获取
     */
    static class MyVersionProvider implements CommandLine.IVersionProvider {

        @Override
        public String[] getVersion() throws Exception {
            final InputStream in = MyVersionProvider.class.getClassLoader().getResourceAsStream("config.properties");
            final Properties p = new Properties();
            p.load(in);
            return new String[]{"My APP", "Version " + p.getProperty("version", "unknown")};
        }
    }
}

进阶

我们知道每个命令行都会有 -h-v这俩选项,所以人家早就考虑好了。

只需要一个选项即可:

@CommandLine.Command(name = "java -jar cli.jar",
					mixinStandardHelpOptions = true,
					versionProvider = CliParam.MyVersionProvider.class)
public class CliParam {}

使用参数解析

定义完了,就需要在main方法里解析了。

    public static void main(String[] args) throws Exception {
        // 解析参数
        final CliParam CliParam = new CliParam();
        final CommandLine commandLine = new CommandLine(CliParam);
        try {
            final CommandLine.ParseResult parseResult = commandLine.parseArgs(args);
            if (parseResult.isUsageHelpRequested()) {
                commandLine.usage(System.out);
                System.exit(0);
            }
            if (parseResult.isVersionHelpRequested()) {
                commandLine.printVersionHelp(System.out);
                System.exit(0);
            }
            CliParam.setINSTANCE(CliParam);
        } catch (CommandLine.ParameterException e) {
            commandLine.usage(System.out);
            System.exit(1);
        }

		// 使用 cliParam

当遇到未知参数时,会抛出 CommandLine.ParameterException, 捕获了打印help即可。
正常解析完如果是 -V,也需要打印版本号然后退出。

更多强大功能,请参考文档

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java8新特性及实战视频教程完整版Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用Lambda 表达式可以使代码变的更加简洁紧凑。Java8实战视频-01让方法参数具备行为能力Java8实战视频-02Lambda表达式初探Java8实战视频-03Lambda语法精讲Java8实战视频-04Lambda使用深入解析Java8实战视频-05Lambda方法推导详细解析-上.wmvJava8实战视频-06Lambda方法推导详细解析-下Java8实战视频-07Stream入门及Stream在JVM中的线程表现Java8实战视频-08Stream知识点总结Stream源码阅读Java8实战视频-09如何创建Stream上集Java8实战视频-10如何创建Stream下集.wmvJava8实战视频-11Stream之filter,distinct,skip,limit,map,flatmap详细介绍Java8实战视频-12Stream之Find,Match,Reduce详细介绍Java8实战视频-13NumericStream的详细介绍以及和Stream之间的相互转换Java8实战视频-14Stream综合练习,熟练掌握API的用法Java8实战视频-15在Optional出现之前经常遇到的空指针异常.wmvJava8实战视频-16Optional的介绍以及API的详解Java8实战视频-17Optional之flatMap,综合练习,Optional源码剖析Java8实战视频-18初识Collector体会Collector的强大Java8实战视频-19Collector使用方法深入详细介绍-01Java8实战视频-20Collector使用方法深入详细介绍-02Java8实战视频-21Collector使用方法深入详细介绍-03.wmvJava8实战视频-22Collector使用方法深入详细介绍-04Java8实战视频-23Collector原理讲解,JDK自带Collector源码深度剖析Java8实战视频-24自定义Collector,结合Stream的使用详细介绍Java8实战视频-25Parallel Stream编程体验,充分利用多核机器加快计算速度Java8实战视频-26Fork Join框架实例深入讲解Java8实战视频-27Spliterator接口源码剖析以及自定义Spliterator实现一个Stream.wmvJava8实战视频-28Default方法的介绍和简单的例子Java8实战视频-29Default方法解决多重继承冲突的三大原则详细介绍Java8实战视频-30多线程Future设计模式原理详细介绍,并且实现一个Future程序Java8实战视频-31JDK自带Future,Callable,ExecutorService介绍Java8实战视频-32实现一个异步基于事件回调的Future程序.wmvJava8实战视频-33CompletableFuture用法入门介绍Java8实战视频-34CompletableFuture之supplyAsync详细介绍Java8实战视频-35CompletableFuture流水线工作,join多个异步任务详细讲解Java8实战视频-36CompletableFuture常用API的重点详解-上Java8实战视频-37CompletableFuture常用API的重点详解-下Java8实战视频-38JDK老DateAPI存在的问题,新的DateAPI之LocalDate用法及其介绍.wmvJava8实战视频-39New Date API之LocalTime,LocalDateTime,Instant,Duration,Period详细介绍Java8实战视频-40New Date API之format和parse介绍

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值