【问题标题】:jCommander - throw Exception for unknown and unused value?jCommander - 为未知和未使用的值抛出异常?
【发布时间】:2016-03-07 22:28:21
【问题描述】:

我正在使用 JCommander 1.48,我遇到了以下问题:

例如我有这些参数:

@Parameter(names = "user", description = "the User")
private String user;
@Parameter(names = "password", description = "the password")
private String password

我正在使用以下参数运行我的程序:

--user hugo --password secret

和:

--user hugo david --password secret

两者都相当于相同的解决方案,程序运行完美。但是如果参数的值太多,我希望程序抛出异常。我知道“arity”(参数值的数量)作为@Parameter 注释的配置,但字符串的默认值已经为 1。似乎在第一个值之后一切都被忽略了,只要它不是另一个参数。

有什么解决方案或想法吗?

编辑:

基本解决方案(由 assylias 发布)对我不起作用。更准确的例子:

public class MyTestProgram {
    private final Params options;
    public MyTestProgram(String[] args) {
        options = new Params();
        new JCommander(options).parse("--user hugo david --password secret".split(" "));
        //pass "args" to parse() instead of hardcoded string.
    }

    public static void main(String[] args) throws Exception {
        System.setProperty("org.jboss.logging.provider", "slf4j");
        new MyTestProgram(args);
    }
}

public class Params {
    @Parameter
    private List<String> parameters = new ArrayList<>();
    @Parameter(names = "--user", description = "the user", required = true)
    private String webuser;
    @Parameter(names = "--password", description = "the password", required = true)

    private String stage;
    //getters and setters
}

这是在实际程序代码开始之前发生的一切。

编辑:assylias 更新的答案解决了问题。

【问题讨论】:

    标签: java annotations command-line-interface jcommander


    【解决方案1】:

    下面的程序根据你的需要抛出异常:

    class Params {
      @Parameter(names = "--user", description = "the User")
      String user;
      @Parameter(names = "--password", description = "the password")
      String password;
    
    }
    
    public static void main(String[] args) {
      Params p = new Params();
      new JCommander(p).parse("--user hugo  david --password secret".split(" "));
      System.out.println(p.user);
      System.out.println(p.password);
    }
    

    如果您删除 david,程序会按预期打印 hugo 和 secret。


    更新

    在您发布的代码中,您有:

    @Parameter
    private List<String> parameters = new ArrayList<>();
    

    如果您阅读javadoc for the names attribute of the Parameter annotation,您会看到(强调我的)它是:

    允许的命令行参数数组(例如“-d”、“--outputdir”等...)。 如果省略此属性,则其注释的字段将接收所有未解析的选项

    所以命令“david”最终出现在parameters 列表中。如果您想要一个异常,则需要删除该参数。

    【讨论】:

    • 我将您的代码复制到一个测试项目中,只是为了检查它是否也适合我。是的,您的代码独立于我的代码工作。不幸的是,我基本上做了同样的事情(从“JCommander(params,args)”更改为 JCommander(params).parse(args)),这根本没有区别,至少对于我的代码来说。为什么我的代码没有为我抛出这个异常?我编辑了这个问题。据我所知,我正在做几乎相同的事情。
    【解决方案2】:

    根据 JCommander 文档,您可以添加自定义参数验证,例如:

    public class SingleValue implements IParameterValidator {
     public void validate(String name, String value) throws ParameterException {
        String[] values = value.split(" ");
        if (values.length > 1) 
        {
          throw new ParameterException("Parameter " + name + " should hold no more than one value, (found " + value +")");
        }
      }
    }
    

    那么你的变量声明将如下所示:

    @Parameter(names = "user", description = "the User", validateWidth = SingleValue.class)
    private String user;
    

    当“--user hugo david --password secret”被传递时应该抛出异常,而不是在“--user hugo --password secret”被传递时抛出异常

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多