java - 如何在java中使用Option类(cli-commons)

标签 java command-line

我正在使用 cli-commons 1.4 库,该库下存在选项类。我正在我的类 CLIReader.java 下创建一个选项类的对象。这是我的代码:

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.log4j.Logger;

public class CLIReader {

private String user = "";
private String password = "";
private String serverUrl = "";
private String streamName = "";
private static String compList;
private static String completeLogger;

public boolean readCommandLineParameters(String[] args) {
Logger log = Logger.getLogger(CLIReader.class);
Options options = new Options();

Option helpOpt = Option.builder("h").longOpt("help").desc("Usage Help").build();
options.addOption(helpOpt);

Option serverurl = Option.builder("url").longOpt("server url").desc("Server url").required().hasArg().argName("url").build();
options.addOption(serverurl);

Option userOpt = Option.builder("u").longOpt("user").desc("User Name").hasArg().argName("user").required().build();
options.addOption(userOpt);

Option pwdOpt = Option.builder("p").longOpt("password").desc("user password").hasArg().argName("password").required().build();
options.addOption(pwdOpt);
Option streamOpt = Option.builder("s").longOpt("streamName").desc("Stream Name").hasArg().argName("streamName").required().build();
options.addOption(streamOpt);

Option configOpt =   Option.builder("c").longOpt("componentList").desc("ComponentListPath").hasArg().argName("compList").required().build();
options.addOption(configOpt);

Option completeLoggerOpt = Option.builder("v").longOpt("completeLogger").desc("Complete Logger Info + Errors").hasArg().argName("yes/no").required().build();
options.addOption(completeLoggerOpt);

try {
  CommandLineParser parser = new DefaultParser();
  CommandLine cmd = parser.parse(options, args, true);

  if (cmd.hasOption("h")) {
    System.out.println("p");
    return false;
  }

  serverUrl = cmd.getOptionValue("url");
  user = cmd.getOptionValue("u");
  password = cmd.getOptionValue("p");
  streamName = cmd.getOptionValue("s");
  compList = cmd.getOptionValue("c");
  completeLogger = cmd.getOptionValue("v").toLowerCase();
}
  catch (Exception e) {
  log.info(e.getMessage());

  HelpFormatter formatter = new HelpFormatter();
  formatter.printHelp("User", options, true);

  return false;
}

return true;
}

public String getUser() {
return user;
}

public String getPassword() {
return password;
}

public String getServerUrl() {
return serverUrl;
}

public String getStreamName() {
return streamName;
}

public String getcompList() {
return compList;
}

public String getcompleteLogger() {
return completeLogger;
}

}

我有两种情况,即

场景 1

当我在命令行提示符中传递此命令时: java -jar abc.jar -u stack -p stackoverflow91 -url https://www.google.com -s streamA -c D:\abc.txt -v

我得到输出:

INFO - Missing required options: v
usage: abc  -c <compList> [-h] -p <password> -s <streamName>
   -u <user> -url <url> -v <yes/no>
-c,--componentList <compList>   ComponentListPath
-h,--help                       Usage Help
-p,--password <password>        user password
-s,--streamName <streamName>    Stream Name
-u,--user <user>                User Name
-url,--server url <url>         Server url
-v,--completeLogger <yes/no>    Complete Logger Info + Errors

这是正确的,因为缺少 v 的值

场景 2

当我在命令行提示符中传递此命令时: java -jar abc.jar -h java -jar abc.jar -help

我得到输出:

INFO - Missing required options:url,s,u,p,c v
usage: abc  -c <compList> [-h] -p <password> -s <streamName>
   -u <user> -url <url> -v <yes/no>
-c,--componentList <compList>   ComponentListPath
-h,--help                       Usage Help
-p,--password <password>        user password
-s,--streamName <streamName>    Stream Name
-u,--user <user>                User Name
-url,--server url <url>         Server url
-v,--completeLogger <yes/no>    Complete Logger Info + Errors

但是我想要的是当我传递这个命令时, java -jar abc.jar -h java -jar abc.jar -help

我希望我的输出为“p”,这是 if 条件内的消息。

任何人都可以帮我解决上面代码中我做错的事情吗?

试用-1

public boolean readCommandLineParameters(String[] args) {
Logger log = Logger.getLogger(CLIReader.class);
Options options = new Options();
boolean hasHelp= false;
Option helpOpt = Option.builder("h").longOpt("help").desc("Usage Help").build();
options.addOption(helpOpt);

Option serverurl = Option.builder("url").longOpt("server url").desc(" Server url").required().hasArg().argName("url").build();
options.addOption(serverurl);

Option userOpt = Option.builder("u").longOpt("user").desc("User Name").hasArg().argName("user").required().build();
options.addOption(userOpt);

Option pwdOpt = Option.builder("p").longOpt("password").desc(" user password").hasArg().argName("password").required().build();
options.addOption(pwdOpt);

//Stream Option added 
Option streamOpt = Option.builder("s").longOpt("streamName").desc("Stream Name").hasArg().argName("streamName").required().build();
options.addOption(streamOpt);

Option configOpt = Option.builder("c").longOpt("componentList").desc("ComponentListPath").hasArg().argName("compList").required().build();
options.addOption(configOpt);

Option completeLoggerOpt = Option.builder("v").longOpt("completeLogger").desc("Complete Logger Info + Errors").hasArg().argName("yes/no").required().build();
options.addOption(completeLoggerOpt);

  try {
  CommandLineParser parser = new DefaultParser();
  CommandLine cmd = parser.parse(options, args, true);
  } 
  if (cmd.hasOption(helpOpt.getOpt()) || cmd.hasOption(helpOpt.getLongOpt()))    {
    System.out.println("yes");
    hasHelp = true;
}

  serverUrl = cmd.getOptionValue("url");
  user = cmd.getOptionValue("u");
  password = cmd.getOptionValue("p");
  streamName = cmd.getOptionValue("s");
  compList = cmd.getOptionValue("c");
  completeLogger = cmd.getOptionValue("v").toLowerCase();
}
catch (Exception e) {
  log.info(e.getMessage());

  HelpFormatter formatter = new HelpFormatter();
 formatter.printHelp("Abc ", options, true);
}

return hasHelp;
}

最佳答案

您的“tryout-1”代码仍然遇到原来的问题。

最初的问题是这样的:您定义 Options 对象,然后使用 required() 添加各种强制选项。现在,无论您做什么,只要您尝试单独使用 -h ,您的 Options 对象就会提示那些缺少强制选项。

link我提供了解决此问题的建议方法 - 但您尚未实现其中任何一个。

正如答案之一所述:

The way we have addressed this situation in the past... is to parse the command line twice.

创建一个不同的 Options 对象,并向其添加 -h - 但仅此而已。首先使用该对象来测试您的命令行。如果命令行包含 -h 则打印用法文本。否则,使用主 Commands 对象来处理所有剩余选项的命令行。

这是该方法的一个非常基本的精简版本 - 它需要清理,但说明了要点:

private String serverUrl = "";

public void readCommandLineParameters(String[] args) {
    // Just the "help" option:
    Options helpOpts = new Options();
    Option helpOpt = Option.builder("h").longOpt("help").desc("Usage Help").build();
    helpOpts.addOption(helpOpt);

    // Everything else:
    Options allOpts = new Options();
    Option serverurl = Option.builder("url").longOpt("server url").required().desc("Server url")
            .hasArg().argName("url").build();
    allOpts.addOption(serverurl);

    boolean hasHelpOption = false;

    CommandLineParser parser = new DefaultParser();
    CommandLine cmd = null;
    try {
        cmd = parser.parse(helpOpts, args, true);
    } catch (ParseException ex) {
        Logger.getLogger(CLIReader.class.getName()).log(Level.SEVERE, null, ex);
    }

    if (cmd.hasOption("h")) {
        System.out.println("p");
        hasHelpOption = true;
    }

    if (!hasHelpOption) {
        CommandLine cmd2 = null;
        try {
            cmd2 = parser.parse(allOpts, args, true);
        } catch (ParseException ex) {
            Logger.getLogger(CLIReader.class.getName()).log(Level.SEVERE, null, ex);
        }
        serverUrl = cmd2.getOptionValue("url");
    }
}

如果您不喜欢这种方法(可能有充分的理由不喜欢它),那么您可以查看该问题中的其他答案。也许其中之一更适合您的需求。

关于java - 如何在java中使用Option类(cli-commons),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60902065/

相关文章:

java - 泛型通配符参数下界到对象

java - 当两个监控字段引用同一个对象时,为什么两个同步块(synchronized block)的行为就像我提供了不同的监控对象一样?

python - 对于 python 初学者来说,自动化流程的一些很好的例子是什么?

linux - 通过 ssh 连接时使用远程服务器的别名

java - 如何从命令提示符在 Java 中将 jar 文件与另一个文件结合使用

python - python optparse的异常处理

xcode - 安装命令行开发工具 : can't install the software because it is not currently available from the software update server

java - 控制和创建多个 Sprite 数组 Java Libgdx

java - 什么时候应该和不应该为了速度/性能而脱离 OOP?

java - 在 Play Framework 中导入 Jar 会出现 java.lang.ClassCastException