Commander是一个用于解析命令行参数的Java框架,支持解析所有基本的数据类型,也支持将命令行解析成用户自定义的类型,只需要写一个转变函数。
1. JCommander用法
将用来表示参数的fields用@Parameter标识:
- import com.beust.jcommander.Parameter;
- public class JCommanderExample {
- @Parameter
- private List<String> parameters = new ArrayList<String>();
- @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity")
- private Integer verbose = 1;
- @Parameter(names = "-groups", description = "Comma-separated list of group names to be run")
- private String groups;
- @Parameter(names = "-debug", description = "Debug mode")
- private boolean debug = false;
- }
JCommander就可以解析命令行中的参数了:
- JCommanderExample jct = new JCommanderExample();
- String[] argv = { "-log", "2", "-groups", "unit" };
- new JCommander(jct, argv);
- Assert.assertEquals(jct.verbose.intValue(), 2);
2. 选项类型
Boolean:
- @Parameter(names = "-debug", description = "Debug mode", arity = 1)
- private boolean debug = true;
boolean类型默认arity=0,这样的话不要用户为参数设置value,只要参数中有-debug就被parse成true,没有就parse成false。但是如果加上 arity=1,则需要用户明确指定value:
- program -debug true
- program -debug false
String,Interger,Long:
对这几种类型,JCommander会尝试parse随后的参数,并上溯成参数的类型,如果参数不能成功上溯则会产生exception
- @Parameter(names = "-log", description = "Level of verbosity")
- private Integer verbose = 1;
- java Main -log 3
- //got exception for the following one
- java Main -log text
Lists:
如果类型是List,则这个参数可出现多次
- @Parameter(names = "-host", description = "The host")
- private List<String> hosts = new ArrayList<String>();
下例中fields hosts包含了两个字符串
- java Main -host host1 -verbose -host host2
Password:
指明password为true表明这个field是password,我们不想他出现在命令行上,遇到password的参数,用户会被要求在prompt中输入密码
- public class ArgsPassword {
- @Parameter(names = "-password", description = "Connection password", password = true)
- private String password;
- }
Echo Input:
当你想让password显示在prompt中时,需要设置echoInput=true,这个setting只有在password=true时才有效
- public class ArgsPassword {
- @Parameter(names = "-password", description = "Connection password", password = true, echoInput = true)
- private String password;
- }
3. 自定义类型
当需要更负责的参数时,比如files,host names,lists等,我们可以写一个转换器(converter)来将参数转换成我们想要的格式或类型。转换器需要实现IStringConverter接口
- public interface IStringConverter<T> {
- T convert(String value);
- }
a. 通过annotation实现:
下面的converter将string转换成file
- public class FileConverter implements IStringConverter<File> {
- @Override
- public File convert(String value) {
- return new File(value);
- }
- }
将参数对应的field定义成下面这样,注意要在annotation里指定converter
- @Parameter(names = "-file", converter = FileConverter.class)
- File file;
b. 通过工厂 factory 实现:
在每个parameter annotation中都指定converter有点烦,可以通过factory解决这个问题。
比如你要将下面的参数解析成host和port java App -target example.com:8080
定义一个类来放参数
- public class HostPort {
- private String host;
- private Integer port;
- }
写个converter把参数String转换成HostPort
- class HostPortConverter implements IStringConverter<HostPort> {
- @Override
- public HostPort convert(String value) {
- HostPort result = new HostPort();
- String[] s = value.split(":");
- result.host = s[0];
- result.port = Integer.parseInt(s[1]);
- return result;
- }
- }
写一个Factory,作用是返回converter
- public class Factory implements IStringConverterFactory {
- public Class<? extends IStringConverter<?>> getConverter(Class forType) {
- if (forType.equals(HostPort.class)) return HostPortConverter.class;
- else return null;
- }
参数类也很简单,参数类型直接用HostPort就好了
- public class ArgsConverterFactory {
- @Parameter(names = "-hostport")
- private HostPort hostPort;
- }
没有看到Factory用在什么地方?是在你的程序创建JCommander时传进去的
- ArgsConverterFactory a = new ArgsConverterFactory();
- JCommander jc = new JCommander(a);
- jc.addConverterFactory(new Factory());
- jc.parse("-hostport", "example.com:8080");
- Assert.assertEquals(a.hostPort.host, "example.com");
- Assert.assertEquals(a.hostPort.port.intValue(), 8080);
4. 参数验证
通过提供一个实现了IParameterValidator接口的类,可以让JCommander验证你的参数
- public interface IParameterValidator {
- /**
- * Validate the parameter.
- *
- * @param name The name of the parameter (e.g. "-host").
- * @param value The value of the parameter that we need to validate
- *
- * @throws ParameterException Thrown if the value of the parameter is invalid.
- */
- void validate(String name, String value) throws ParameterException;
- }
下面这个validator可以验证提供的参数为正整数
- public class PositiveInteger implements IParameterValidator {
- public void validate(String name, String value)
- throws ParameterException {
- int n = Integer.parseInt(value);
- if (n < 0) {
- throw new ParameterException("Parameter " + name + " should be positive (found " + value +")");
- }
- }
- }
在parameter annotation中用validateWith来指定验证器
- @Parameter(names = "-age", validateWith = PositiveInteger.class)
- private Integer age;
5. 主参数
我们可以定义一个main parameter来放所有参数,这个参数不用指定names,必须为List<String>类型
- @Parameter(description = "Files")
- private List<String> files = new ArrayList<String>();
- @Parameter(names = "-debug", description = "Debugging level")
- private Integer debug = 1;
run下面命令行,files会保存‘file1’和‘file2’
- java Main -debug file1 file2
6. 私有参数
参数可以是private的
- public class ArgsPrivate {
- @Parameter(names = "-verbose")
- private Integer verbose = 1;
- public Integer getVerbose() {
- return verbose;
- }
- }
- ArgsPrivate args = new ArgsPrivate();
- new JCommander(args, "-verbose", "3");
- Assert.assertEquals(args.getVerbose().intValue(), 3);
7. 参数分隔符
参数默认用空格分隔,但是我们也可以指定自己的分隔符,比如用“:”, “=”等,java Main -log:3
可以在参数类定义中使用@Parameter annotation指定分隔符
- @Parameters(separators = "=")
- public class SeparatorEqual {
- @Parameter(names = "-level")
- private Integer level = 2;
- }
8. 多重描述(多个参数类)
你可以将参数放在不同的参数类中,比如定义以下两个含有不同参数的参数类
- public class ArgsMaster {
- @Parameter(names = "-master")
- private String master;
- }
- public class ArgsSlave {
- @Parameter(names = "-slave")
- private String slave;
- }
使用时将两个类都传入JCommander
- ArgsMaster m = new ArgsMaster();
- ArgsSlave s = new ArgsSlave();
- String[] argv = { "-master", "master", "-slave", "slave" };
- new JCommander(new Object[] { m , s }, argv);
- Assert.assertEquals(m.master, "master");
- Assert.assertEquals(s.slave, "slave");
9. @语法
JCommander支持从文件中获取并解析参数,比如文件/tmp/params中包含了以下内容
- -verbose
- file1
- file2
- file3
在命令行中用@指定文件路径即可
- java Main @/tmp/parameters
10. 参数value数量(Arities)
有时候你想为一个参数设置多个值,这时就要用到arity,比如-pairs需要两个values,则设置arity=2
- @Parameter(names = "-pairs", arity = 2, description = "Pairs")
- private List<String> pairs;
JCommander就会为pairs接收两个values
- java Main -pairs slave master
注意想接收多个value的参数需要设置成List<String>类型,boolean类型默认arity为0,String、Integer、int、Long、long默认arity都为1。
可变参数值数量,设置variableArity=true,你可以指定一个参数接收不定数量的values
- @Parameter(names = "-foo", variableArity = true)
- public List<String> foo = new ArrayList<String>();
下面两个例子一个接收2个参数,一个接收3个参数
- program -foo a1 a2 a3 -bar
- program -foo a1 -bar
11. 多重选项名
同一个选项(option)可以有不同别名,比如--recursive,可以有一个缩写-r,可以通过给names设置多个值实现
- @Parameter(names = { "-d", "--outputDirectory" }, description = "Directory")
- private String outputDirectory;
下面两种都可以给outputDirectory赋值
- </pre><pre name="code" class="java">java Main -d /tmp
- java Main --outputDirectory /tmp
12. 其他选项配置
JCommander#setCaseSensitiveOptions(boolean):选项是否大小写敏感,如果设置成true,则‘-option' 和'-OPTION'是不同的选项
JCommander#setAllowAbbreviatedOptions(boolean):打开选项缩写功能,’-op‘可以表示’-option‘选项,如果选项缩写太模糊不能定位到某个选项,则会throw一个ParameterException
13. 必须和可选选项
@Parameter annotation的required设置为true则表示此选项为必须的,否则为可选(默认为可选)
- @Parameter(names = "-host", required = true)
- private String host;
14. 默认值
一般情况下直接给选项赋值就可以了
- private Integer logLevel = 3;
如果有更复杂的情况,比如对某些选项可以再不同的类里重复使用,或者你想把所有的default value都存在同一个地方比如一个XML文件,这些可以通过实现IDefaultProvider接口达成
- public interface IDefaultProvider {
- /**
- * @param optionName The name of the option as specified in the names() attribute
- * of the @Parameter option (e.g. "-file").
- *
- * @return the default value for this option.
- */
- String getDefaultValueFor(String optionName);
- }
实例
- //这是个内部类
- private static final IDefaultProvider DEFAULT_PROVIDER = new IDefaultProvider() {
- @Override
- public String getDefaultValueFor(String optionName) {
- return "-debug".equals(optionName) ? "false" : "42";
- }
- };
- // ...
- JCommander jc = new JCommander(new Args());
- jc.setDefaultProvider(DEFAULT_PROVIDER); //把default provider传入
15. 帮助选项
非常简单
- @Parameter(names = "--help", help = true)
- private boolean help;
16. 更多复杂的命令语法
想git之类的工具,除了git命令本身需要选项,它还包含一些子命令,如git commit,子命令本身也包含一些选项
- git commit --amend -m "Bug fix"
上面的命令中,commit在JCommander中叫做’commands‘, 我们要为这个子命令单独创建一个类
- @Parameters(separators = "=", commandDescription = "Record changes to the repository")
- private class CommandCommit {
- @Parameter(description = "The list of files to commit")
- private List<String> files;
- @Parameter(names = "--amend", description = "Amend")
- private Boolean amend = false;
- @Parameter(names = "--author")
- private String author;
- }
再为另一个git命令add创建一个类
- @Parameters(commandDescription = "Add file contents to the index")
- public class CommandAdd {
- @Parameter(description = "File patterns to add to the index")
- private List<String> patterns;
- @Parameter(names = "-i")
- private Boolean interactive = false;
- }
创建好后要在JCommander对象里通过addCommand注册这些命令,当然我们也可以创建一个主要的参数类来接受git的参数
- CommandMain cm = new CommandMain();
- JCommander jc = new JCommander(cm);
- CommandAdd add = new CommandAdd();
- jc.addCommand("add", add);
- CommandCommit commit = new CommandCommit();
- jc.addCommand("commit", commit);
- jc.parse("-v", "commit", "--amend", "--author=cbeust", "A.java", "B.java");
- Assert.assertTrue(cm.verbose);
- Assert.assertEquals(jc.getParsedCommand(), "commit");
- Assert.assertTrue(commit.amend);
- Assert.assertEquals(commit.author, "cbeust");
- Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java"));
17. Exception
JCommander发现错误时会抛出ParameterExcpetion,这是一个runtime exception
18. usage
可以再JCommander实例中调用usage()方法获取命令行使用方法
19. 隐藏参数
如果不想某些选项出现在usage里,可以隐藏他们
- @Parameter(names = "-debug", description = "Debug mode", hidden = true)
- private boolean debug = false;
20. 国际化
选项的描述(description)可以国际化,首先在类上使用@Parameter指定消息bundle的名字,然后在选项的@Parameter中使用descriptionKey指定bundle中的key
- @Parameters(resourceBundle = "MessageBundle")
- private class ArgsI18N2 {
- @Parameter(names = "-host", description = "Host", descriptionKey = "host")
- String hostName;
- }
在MessageBundle中,定义host如下
- host:主机
21. 参数代理
使用@ParameterDelegate可以在主参数类中引用其他的代理参数类
- class Delegate {
- @Parameter(names = "-port")
- private int port;
- }
- class MainParams {
- @Parameter(names = "-v")
- private boolean verbose;
- @ParametersDelegate
- private Delegate delegate = new Delegate();
- }
使用时只需在JCommander中指定主参数类
- MainParams p = new MainParams();
- new JCommander(p).parse("-v", "-port", "1234");
- Assert.assertTrue(p.isVerbose);
- Assert.assertEquals(p.delegate.port, 1234);
22. 动态参数
JCommander允许接收没有预先定义的选项,比如’-Da=b -Dc=d‘, Da和Dc没有在参数类中定义,这些参数要用@DynamicParameter annotation标记的类型为Map<String, String>的选项接收,动态参数可以重复多次
- @DynamicParameter(names = "-D", description = "Dynamic parameters go here")
- private Map<String, String> params = new HashMap<String, String>();
通过使用assignment属性,可以用其他符号代替’=‘作为赋值符号
http://blog.csdn.net/navyhu/article/details/40430267
相关推荐
JCommander 是由Cédric Beust开发的一个更高级的命令行参数解析库,尤其适用于具有多个命令或子命令的复杂应用。JCommander允许你定义多个命令模型类,每个类对应一个命令,每个命令有自己的参数。它还支持命令行...
1. **参数解析**:识别参数类型,如单值参数、开关参数(如`-v`或`--verbose`)和复合参数(如`--file path/to/file`)。 2. **参数验证**:检查参数的有效性,例如确保必需的参数已提供,或者参数值符合预期格式。...
在Java中,通常我们会使用如Apache Commons CLI、JCommander或jopt-simple等库来解析命令行参数。jflag作为一个轻量级的替代品,可能旨在提供更简洁的代码实现,减少依赖,并可能专注于基本功能,使开发者能够快速...
`jcommander`是一个Java库,用于命令行参数解析,它简化了从命令行参数中提取和验证数据的过程。 描述中提到的“打包找不到 jcommander COULD NOT FIND jcommander-1.48”表明在构建过程中,Maven或Gradle无法从...
- 对于复杂的命令行参数,可以使用第三方库,如Apache Commons CLI或JCommander。这些库可以帮助解析和验证命令行参数,提供更友好的用户界面。 - 如果只是简单的参数处理,可以手动解析`args`数组,例如检查参数...
总之,"反编译class文件必备"是一个关于Java开发中的高级技巧,它涉及到对字节码的理解、使用反编译工具以及可能的命令行参数解析,这些都是成为出色Java开发者和架构师道路上不可或缺的技能。通过学习和实践这些...
4. **命令行参数解析**:项目可能使用了如Apache Commons CLI或JCommander等第三方库来处理命令行参数,允许用户自定义生成配置文件的选项。 5. **异常处理**:在处理I/O操作时,异常处理是必不可少的。源码中应...
JCommander可以解析命令行参数,确定用户想要执行的操作(如生成或扫描条形码),而ZXing则负责实际的条形码处理工作。 在实际项目中,首先你需要将`zxing.3.3.1.jar`和`jcommander.1.48.jar`添加到你的项目类路径...
3. **jcommander-1.72.jar**:这是一个命令行参数解析库,与ZXing库一起使用时,可以帮助开发者更方便地处理命令行输入。例如,如果你打算创建一个命令行工具来读取或生成条码,jcommander可以帮助解析命令行参数,...
`clipp`是一个基于Scala的命令行接口(CLI)参数解析器库,它为开发者提供了便利的方式来处理命令行输入,并生成详细的用法信息。在开发命令行工具时,正确解析和管理用户输入的参数是至关重要的,`clipp`正是为此...
这个解析器使得在Java程序中处理命令行参数和选项变得更加简单和直观。它可能包含了源代码、示例、文档以及相关的构建文件,帮助开发者轻松地实现对命令行输入的解析和验证,从而提高程序的可交互性和用户友好性。 ...
除了TestNG本身,你还需要JCommander库,这是一个用于命令行参数解析的工具,常常在TestNG测试中用于处理命令行输入。JCommander的下载地址同样需要访问官方网站或者通过Maven/Gradle等构建工具获取对应的依赖。在你...
3. **jcommander-1.48.jar** - JCommander是一个解析命令行参数的库,常用于工具或命令行应用,帮助处理复杂的命令行选项和参数。 4. **commons-logging-1.1.3.jar** - Apache Commons Logging是一个日志抽象层,...
JCommander 1.0的发布,作为一个命令行参数解析库,简化了Java应用程序的命令行接口开发。 这一期的JavaEye月刊涵盖了从IDE到框架,再到数据库和开发工具的广泛内容,反映了当时Java生态系统的重要动态,对于学习和...
此外,为了实现类似命令行工具的功能,例如指定IP段或设置超时,可以使用命令行参数解析库,如Apache Commons CLI或JCommander。这样,用户可以通过提供不同的参数来定制ping行为。 总结来说,Java Ping程序是一个...
4. `jcommander-1.48.jar`:JCommander 是一个帮助处理命令行参数的Java库,ZXing可能使用它来解析用户输入,方便在命令行界面中使用ZXing的功能。 5. `javase-3.3.0.jar`:这个文件是ZXing的Java Standard Edition...
对于Perun-java-cli来说,可能使用了Java的IO流进行文件操作,使用了Apache Commons CLI或者JCommander等库来处理命令行参数,还可能使用了HTTP客户端库如OkHttp或Apache HttpClient来与Perun服务端进行通信。...
- 命令行参数解析是CmdShop的核心功能,可能使用了如JCommander或Apache Commons CLI等第三方库来处理命令行参数。 3. **项目构建与管理**: - CmdShop很可能使用Maven或Gradle作为构建工具,这两个工具可以管理...
参数解析是指从输入的字符串或者命令行中提取出有意义的数据,这些数据可以是数值、开关、选项等。在“ScreenCaptureProcess5”中,参数解析可能用于定制截图的特定行为,比如设置输出格式、尺寸、延迟时间等。参数...
9. **命令行解析**:系统可能使用如JCommander这样的库来解析命令行参数,使得用户输入的命令能被正确识别和执行。 10. **用户交互设计**:尽管是命令行应用,但依然需要考虑用户体验,如提供友好的提示信息,错误...