使用JCommander开发命令行交互(CLI)式JAVA程序

一、前言

最近在看pulsar源码时,发现他们使用了JCommander来开发命令行交互程序,便对这个framework产生了兴趣。 传统意义上讲,JAVA并不是开发命令行程序最合适的语言,但是因为依赖一些特定JAVA库(特别是大数据相关的)的CLI程序,用java来开发却是最方便的。

二、常见的linux命令行风格

首先我们先了解下常见的linux命令行风格:

  • Unix 风格参数,前面加单破折线 -
  • BSD 风格参数,前面不加破折线
  • GNU 风格参数,前面加双破折线 --
  • JAVA 风格参数

Unix风格

Unix是从贝尔实验室开发的AT&T Unix系统上原有的命令继承下来的。

ls -a
ls -lah

-后面可以跟多个字母,多个字母就是多个参数

BSD风格

ps aux

参数不带-

GNU风格

两个减号 -- 加参数,一般后边的参数是跟上一个单词或短语

ps --no-headers

当然Unix和GUN风格很多混用,如ls -a 等于ls --all,-h 往往对应 --help

JAVA风格

比如java的命令行,-后面直接是单词

java -version

java -Djava.awt.headless=true -Djava.net.useSystemProxies=true Foo

三、JCommander

快速入门

首先我们看下官方的demo快速入门

java源程序

public class JCommanderTest {
    @Parameter
    public List<String> parameters = Lists.newArrayList();
 
    @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity")
    public Integer verbose = 1;
 
    @Parameter(names = "-groups", description = "Comma-separated list of group names to be run")
    public String groups;
 
    @Parameter(names = "-debug", description = "Debug mode")
    public boolean debug = false;

    @DynamicParameter(names = "-D", description = "Dynamic parameters go here")
    public Map<String, String> dynamicParams = new HashMap<String, String>();

}

所以我们这样调用

JCommanderTest jct = new JCommanderTest();
String[] argv = { "-log", "2", "-groups", "unit1,unit2,unit3",
                    "-debug", "-Doption=value", "a", "b", "c" };
JCommander.newBuilder()
  .addObject(jct)
  .build()
  .parse(argv);

Assert.assertEquals(2, jct.verbose.intValue());
Assert.assertEquals("unit1,unit2,unit3", jct.groups);
Assert.assertEquals(true, jct.debug);
Assert.assertEquals("value", jct.dynamicParams.get("option"));
Assert.assertEquals(Arrays.asList("a", "b", "c"), jct.parameters);

不难发现,JCommander有如下几个特点:

  • 注解驱动:@DynamicParameter(names = "-D", description = "Dynamic parameters go here") 一个类似注解(装饰)轻松做到命令行参数与属性的映射
  • 功能强大:支持多种风格,并可自动生成文档
  • 拓展性强

Jcommander属性值

  • names 设置命令行参数,如-old
  • required 设置此参数是否必须
  • description 设置参数的描述
  • order 设置帮助文档的顺序
  • help 设置此参数是否为展示帮助文档或者辅助功能

其中help最为强大,如demo

    @Parameter(names = "--help", help = true, order = 5)
    private boolean help;

则如下使用即可生成完善的文档

        if (help) {
            jCommander.usage();
            return;
        }
Usage: <main class> [options]
  Options:
    --help

    -debug
      Debug mode
      Default: true
    -host
      The host
      Default: []
    -password
      Connection password

密码类参数处理

在实际程序中,我们往往会遇到很多类似要输入密码的场景。此时我们并不希望密码出现在history中,你可以使用password这种类型,这样JCommander会让你在console中输入。

public class ArgsPassword {
  @Parameter(names = "-password", description = "Connection password", password = true)
  private String password;
}

正则表达式校验

当用户产生于预期不一致的输入时,我们希望便捷地使用正则表达式来校验这些值。

@Parameter(names = "-v",  validateWith = RegexValidator.class)
@Regex("(2\\.0|1\\.0)")
private String version = "2.0";

其他

当然我们还可以使用Apache Commons CLI实现相关功能

四、参考

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏代码世界

Flask之wtforms

WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。

1505
来自专栏抠抠空间

Flask之WTForms

WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。

1123
来自专栏芋道源码1024

分布式作业 Elastic-Job-Lite 源码分析 —— 注册中心

ZookeeperRegistryCenter,基于 Zookeeper 注册中心。从上面的类图可以看到,ZookeeperRegistryCenter 实现 ...

1612
来自专栏用户画像

逻辑覆盖 测试题

(2)  简述什么是测试用例。白盒测试的动态测试要根据程序的控制结构设计测试用例简述其原则。

752
来自专栏python学习路

三、scrapy后续 LinkExtractorsrules Logging发送POST请求内置设置参考手册

CrawlSpiders 通过下面的命令可以快速创建 CrawlSpider模板 的代码: scrapy genspider -t crawl tencent ...

5344
来自专栏我的小碗汤

来看三个问题

是否允许在HTTP请求时,返回原始请求体数据字节,默认为false(GET or HEAD or 上传文件请求除外)。

1051
来自专栏前端新视界

关于 devbridge-autocomplete 插件多选操作的实现方法

目前据我所知最好用的 autocomplete 插件就是 jquery-ui 的 autocomplete 以及 devbridge 的 autocomplet...

2068
来自专栏无题

线程安全与锁优化——深入理解JVM阅读笔记

我根据我的理解把一些关键的要点整理了出来,并对其中一些内容作了删改。 参考地址:http://www.cnblogs.com/pacoson/p/5351355...

3595
来自专栏友弟技术工作室

Beego Controllercontroller 逻辑控制器介绍Controller中数据参数处理获取参数

controller就是处理具体的逻辑的,router将请求分发到指定的controlller,controller处理请求,然后返回。 首先我们还是从源码分...

2862
来自专栏友弟技术工作室

beego路由配置路由设置

web框架中,路由是重要的一环,对于beego的路由配置如何? 让我们从入口文件先分析起来吧:

4141

扫码关注云+社区

领取腾讯云代金券