如何使用commons-cli在Java中检测和解析命令选项?

786 阅读5分钟

当你在终端中输入命令时,无论是启动GUI应用还是仅仅是终端应用,通常都有一些选项(有时称为开关标志),你可以用来修改应用程序的运行方式。这是由POSIX规范设定的标准,所以对于一个Java程序员来说,知道如何检测和解析选项是非常有用的。

在Java中,有几种解析选项的方法。我最喜欢的是Apache Commons CLI库,简称为commons-cli

安装commons-cli

如果你使用Maven等项目管理系统和IDE,你可以在项目属性(如pom.xml 或Eclipse或NetBeans的配置界面)中安装Apache Commons CLI库。

如果你是手动管理库,你可以从Apache网站上下载最新版本。几个JAR文件捆绑在一起。唯一需要的JAR是commons-cli-X.Y.jar (其中X和Y是最新的版本号。)手动或在IDE中把该JAR添加到你的项目中,然后你就可以在代码中使用它。

将一个库导入你的Java代码中

要在你的代码中使用commons-cli库,你必须导入它。对于这个简单的选项解析例子,你可以用标准的最小代码填充一个名为Main.java 的文件。

package com.opensource.myoptparser;
import org.apache.commons.cli.*;
public class Main {
    public static void main(String[] args) {
    // code
    }
}

现在你就可以在Java中解析选项了。

在Java中定义布尔选项

要解析选项,你必须做的第一件事就是定义你的应用程序可以接受的有效选项。使用Option (单数)类来创建选项对象,使用Options (复数)类来帮助跟踪你在项目中创建的所有选项。

首先,为你的选项创建一个组,并按照惯例将其称为options

    //code
    Options options = new Options();

接下来,通过列出一个短选项、一个长选项、一个默认的布尔值和一个帮助信息来定义你的各个选项。然后设置该选项是否需要,最后将该选项添加到options 对象中,该对象包含了你所有的选项。在这个例子中,我只创建了一个选项,随意地称为alpha

    //define options
    Option alpha = new Option("a", "alpha", false, "Activate feature alpha");
    options.addOption(alpha);

在Java中定义带有参数的选项

有时你想让用户在提供选项的同时提供以外的信息。你可能想让用户参考一个配置文件,一个输入文件,或者任何像日期或颜色的设置。为此,你使用builder 方法,根据一个选项的短版本为其创建属性(例如,-c 是一个短选项,--config 是一个长选项)。一旦它被定义,你就把新的选项添加到你的options 组。

    Option config = Option.builder("c").longOpt("config")
        .argName("config")
        .hasArg()
        .required(true)
        .desc("set config file").build();
    options.addOption(config);

通过builder 函数,你可以设置短版本、长版本、是否需要(在这段代码中我把它设置为,所以除非用户在启动时提供这个选项,否则我的应用程序不能运行)、帮助信息等等。

用Java解析选项

在定义了所有可能的选项后,你现在可以遍历用户提供的参数,检查是否有任何参数与你批准的有效短选项列表相匹配。要做到这一点,你要创建一个CommandLine本身的实例,它包含了所有由用户提供的参数(有效的选项和其他)。你还要创建一个CommandLineParser对象,我在代码中称之为parser ,以方便对这些参数进行交互。最后,你可以创建一个HelpFormatter对象(我称之为helper ),以便在缺少必要的选项或使用--help-h 选项时自动向用户提供有用的信息。

    // define parser
    CommandLine cmd;
    CommandLineParser parser = new BasicParser();
    HelpFormatter helper = new HelpFormatter();

最后,添加一些条件语句来分析用户作为命令行输入提供的选项(发现并存储在cmd 变量中)。这个示例程序有两种不同类型的选项,但在这两种情况下,你都可以用.hasOption 方法加上简短的选项名称来检查该选项是否存在。当检测到一个选项时,你可以对数据做任何需要做的事情。

try {
    cmd = parser.parse(options, args);
    if(cmd.hasOption("a")) {
    System.out.println("Alpha activated");
    }
    if (cmd.hasOption("c")) {
    String opt_config = cmd.getOptionValue("config");
    System.out.println("Config set to " + opt_config);
    }
} catch (ParseException e) {
    System.out.println(e.getMessage());
    helper.printHelp("Usage:", options);
    System.exit(0);
}

解析的行为可能会产生一个错误,因为有时需要的-c--config 选项可能丢失。在这种情况下,会打印一条帮助信息,并立即结束应用程序。由于这个错误(Java术语中的异常),你必须修改main方法的开始部分,以声明一个可能的异常。

public static void main(String[] args) throws ParseException {

现在,该示例程序已经完成。

测试你的代码

你可以在你的IDE中通过调整传递给你的代码的默认参数来测试这个应用程序,或者直接建立一个JAR文件并从你的终端运行它。这方面的过程因你的IDE而异。请参考你的IDE文档,阅读我写的如何LINK-TO-ARTICLE[构建JAR]的文章,或者看Daniel Oh写的如何用Maven做同样的事情。

首先,通过省略所需的-c--config 选项,确认解析器异常。

$ java -jar dist/myapp.jar
Missing required option: c
usage: Usage:
 -a,--alpha             Activate feature alpha
 -c,--config    Set config file

用所提供的选项再试一下。

java -jar dist/myantapp.jar --config foo -a
Alpha activated
Config set to foo

选项解析

为用户加入选项是任何应用程序的一个重要功能。Java和Apache commons使它很容易做到。

这里有完整的示范代码供你参考。

package com.opensource.myapp;
import org.apache.commons.cli.*;
public class Main {
    /**
     * @param args the command line arguments
     * @throws org.apache.commons.cli.ParseException
     */
    public static void main(String[] args) throws ParseException {
        // define options
        Options options = new Options();
        Option alpha = new Option("a", "alpha", false, "Activate feature alpha");
        options.addOption(alpha);
        Option config = Option.builder("c").longOpt("config")
                .argName("config")
                .hasArg()
                .required(true)
                .desc("Set config file").build();
        options.addOption(config);
        // define parser
        CommandLine cmd;
        CommandLineParser parser = new BasicParser();
        HelpFormatter helper = new HelpFormatter();
        try {
            cmd = parser.parse(options, args);
            if(cmd.hasOption("a")) {
                System.out.println("Alpha activated");
            }
            if (cmd.hasOption("c")) {
                String opt_config = cmd.getOptionValue("config");
                System.out.println("Config set to " + opt_config);
            }
        } catch (ParseException e) {
            System.out.println(e.getMessage());
            helper.printHelp("Usage:", options);
            System.exit(0);
        }
    }
}

使用Java和选项

选项允许用户修改命令的工作方式。在使用Java时,有很多方法可以解析选项,而commons-cli 是一个强大而灵活的开源解决方案。在你的下一个Java项目中试一下吧。