1

当指定为程序参数的选项无效(在预定义的选项列表中不可用)时,我想要打印使用帮助消息。

      CommandLineParser parser = new BasicParser();
    try {
        CommandLine line = parser.parse(getOptions(), args);
    }
    catch( ParseException exp ) {
        getLogger().info("Invalid command line option name. "+exp.getMessage());
        HelpFormatter hf = new HelpFormatter();
        hf.printHelp("destDir", getOptions());
        return false;
    }       
    return true;

我键入作为参数“测试”字符串。我在想,无效的选项会导致解析器抛出 ParseException,但事实并非如此。我怎样才能实现这种行为?这个图书馆有可能吗?现在它只是省略了无效的参数。

UPDATE Actually it throws exception when option has a '-' prefix. 所以'-Test'会导致抛出异常,但'Test'不会。无论如何我的问题仍然有效,如何强制解析器在无效参数上抛出异常

4

3 回答 3

1

除了程序名称之外,命令行有两种类型的条目,选项(用-or指定--)和我将调用的参数(可能有一个更好的名称,但我不知道它是什么!)有前缀。例如,对于ls

ls -la foo

选项是-land -a,参数是foo(要列出的目录)。当您使用 commons-cli 解析命令行时,它只关心选项,而忽略其他所有内容。这就是为什么如果你添加(不是选项)它不会失败,Test但如果你添加-Test.

于 2016-10-17T15:07:38.640 回答
0

尽管adamreeve提供的答案非常好并且我接受它,但我决定扩展默认解析器功能以防止输入无效选项,即使没有“-”或“--”符号。我制作了自己的自定义解析器:

public class StrictParser extends Parser {

    @Override
    protected String[] flatten(Options opts, String[] arguments, boolean stopAtNonOption) {
        return arguments;
    }

    @Override
    public CommandLine parse(Options options, String[] arguments, boolean stopAtNonOption) throws ParseException {

        CommandLine cmd = null;
        List<String> tokenList = Arrays.asList(flatten(getOptions(), arguments, stopAtNonOption));
        ListIterator<String> iterator = tokenList.listIterator();

        boolean eatTheRest = false;
        setOptions(options);
        cmd = super.parse(options, arguments, stopAtNonOption);

        while (iterator.hasNext()) {
            String token = (String) iterator.next();
            if (!token.startsWith("--") && !token.startsWith("-")) {
                if (stopAtNonOption) {
                        throw new UnrecognizedOptionException("Unrecognized option: " + token +". Every option must start with '--' or '-'", token);
                }
            } else {
                eatTheRest = true;
            }

            if (eatTheRest) {
                iterator.next();
            }
        }
        return cmd;
    }
}

在此解决方案中,任何键入的不带“--”或“-”的 cli 参数都会引发 UnrecognizedOptionException。这不是完美的解决方案,但它展示了它是如何完成的,并且可以成为其他解决方案的良好起点。例如,我们可以接受不带“--”和“-”的选项,但检查该选项是否正确。那么我们需要改变

        if (stopAtNonOption) {
                throw new UnrecognizedOptionException("Unrecognized option: " + token +". Every option must start with '--' or '-'", token);
        }

        if (stopAtNonOption) {                  
            if(!getOptions().hasOption(token)){                     
                throw new UnrecognizedOptionException(
                        "Unrecognized option: " + token, token);
            }
        }

(忽略这个丑陋的三个嵌套 if ;))每个选项也只接受一个参数,但正如我已经提到的,它只是实现对默认解析器的其他修改的起点

于 2016-11-03T07:56:05.030 回答
-1

是的,您可以,您必须创建自定义异常,例如:

public class ParseException extends Exception{
        ParseException(String msg){
             super(msg);  
        }
}

并进入代码:

CommandLineParser parser = new BasicParser();
    try {
        CommandLine line = parser.parse(getOptions(), args);
    }
    catch( Exception exp ) {
       throw new ParseException("Invalid Arguments");
    }       
    return true;

以上方法应该抛出

throws ParseException

所以它的调用者如果传递无效参数将得到 ParseException

于 2016-10-17T09:13:28.653 回答