使用 JCommander 解析命令行参数
如果你想构建一个支持命令行参数的程序,那么 jcommander 非常适合你,jcommander 是一个只有几十 kb 的 Java 命令行参数解析工具,可以通过注解的方式快速实现命令行参数解析。
这篇教程会通过介绍 jcommadner ,快速的创建一个命令行程序,最后支持的命令参数功能如下图。
【资料图】
这个命令行工具仿照 git 操作命令,主要提供了如下功能命令:
1. git-app.jar -help查看命令帮助信息。
2. git-app.jar -version查看当前版本号。
3. git-app.jar clone http://xxxx通过 URL 克隆一个仓库。
4. git-app.jar add file1 file2暂存 file1 文件 file2 文件。
5. git-app.jar commit -m "注释"提交并添加注释。
jcommander 引入截止文章编写时间,最新版本如下:
jcommander 参数绑定com.beust jcommander 1.82
命令行解析中,参数解析与绑定是最实用的一个场景,jcommander 使用 Parameter注解进行参数绑定。我们定义一个 GitCommandOptions.java类来测试参数绑定。
package com.wdbyte.jcommander.v1;import com.beust.jcommander.Parameter;/** * @author https://www.wdbyte.com */public class GitCommandOptions { @Parameter(names = {"clone"}, description = "克隆远程仓库数据") private String cloneUrl; public String getCloneUrl() { return cloneUrl; }}
使用 jcommander 结合 GitCommandOptions 来解析参数。
package com.wdbyte.jcommander.v1;import com.beust.jcommander.JCommander;/** * @author https://www.wdbyte.com */public class GitApp { public static void main(String[] args) { // args = new String[]{"clone","http://www.wdbyte.com/test.git"}; GitCommandOptions gitCommandOptions = new GitCommandOptions(); JCommander commander = JCommander.newBuilder() .addObject(gitCommandOptions) .build(); commander.parse(args); System.out.println("clone " + gitCommandOptions.getCloneUrl()); }}
打包后可以执行命令参数:
$ java -jar git-app.jar clone http://www.wdbyte.com/test.gitclone http://www.wdbyte.com/test.git
这里是一个字符串参数,需要在命令中输出参数值,对于 boolean 类型的参数,不需要传值,有命令即为 true 值。
参数名称@Parameter注解中的 names属性可以定义参数的名称。且可以指定多个参数名称,让我再添加 version参数和 help参数,同时设置参数别名。这两个参数是 boolean 类型。
@Parameter(names = {"help", "-help", "-h"}, description = "查看帮助信息", help = true)private boolean help;@Parameter(names = {"version", "-version", "-v"}, description = "显示当前版本号")private boolean version = false;参数限制
clone参数可以接受一个要克隆的 URL 链接,但是正常情况下只需要一个 URL 链接。可以通过 arity = 1进行限制。
@Parameter(names = {"clone"}, description = "克隆远程仓库数据", arity = 1)private String cloneUrl;帮助信息
使用 usage()参数可以打印命令帮助信息。
GitCommandOptions gitCommandOptions = new GitCommandOptions();JCommander commander = JCommander.newBuilder() .addObject(gitCommandOptions) .build();commander.parse(args);// 打印帮助信息commander.usage();
运行输出帮助信息:
$ java -jar git-app.jarUsage:[options] Options: clone 克隆远程仓库数据 help, -help, -h 查看帮助信息 version, -version, -v 显示当前版本号 Default: false
虽然正确的输出了帮助信息,但是其中有 main class这段,是因为我们没有指定项目名称,我们指定项目名称为 git-app。
JCommander commander = JCommander.newBuilder() .programName("git-app") .addObject(gitCommandOptions) .build();参数排序
在帮助信息中,如果想要自定义参数顺序,可以通过 order = 来排序,数字越小越靠前。
@Parameter(names = {"version", "-version", "-v"}, description = "显示当前版本号", order = 2)private boolean version = false;参数绑定完整测试
package com.wdbyte.jcommander.v2;import com.beust.jcommander.Parameter;/** * @author https://www.wdbyte.com */public class GitCommandOptions { @Parameter(names = {"help", "-help", "-h"}, description = "查看帮助信息", order = 1, help = true) private boolean help; @Parameter(names = {"clone"}, description = "克隆远程仓库数据", order = 3, arity = 1) private String cloneUrl; @Parameter(names = {"version", "-version", "-v"}, description = "显示当前版本号", order = 2) private boolean version = false; //...get method}
GitApp.java
package com.wdbyte.jcommander.v2;import com.beust.jcommander.JCommander;public class GitApp { public static void main(String[] args) { GitCommandOptions gitCommandOptions = new GitCommandOptions(); JCommander commander = JCommander.newBuilder() .programName("git-app") .addObject(gitCommandOptions) .build(); commander.parse(args); // 打印帮助信息 if (gitCommandOptions.isHelp()) { commander.usage(); return; } if (gitCommandOptions.isVersion()) { System.out.println("git version 2.24.3 (Apple Git-128)"); return; } if (gitCommandOptions.getCloneUrl() != null) { System.out.println("clone " + gitCommandOptions.getCloneUrl()); } }}
运行测试:
jcommander 参数验证在上面的例子中, 假设 clone 命令传入的参数必须是一个 URL,那么我们就要进行参数验证,jcommander 也提供了特有的参数验证方式。
1. 编写参数验证类,需要实现 IParameterValidator接口。
package com.wdbyte.jcommander.v3;import java.net.MalformedURLException;import java.net.URL;import com.beust.jcommander.IParameterValidator;import com.beust.jcommander.ParameterException;/** * @author https://www.wdbyte.com */public class UrlParameterValidator implements IParameterValidator { @Override public void validate(String key, String value) throws ParameterException { try { new URL(value); } catch (MalformedURLException e) { throw new ParameterException("参数 " + key + " 的值必须是 URL 格式"); } }}
2. clone参数指定验证类。
@Parameter(names = {"clone"}, description = "克隆远程仓库数据", validateWith = UrlParameterValidator.class, order = 3, arity = 1)private String cloneUrl;
运行测试:
$ java -jar git-app.jar clone https://www.wdbyte.com/test.gitclone https://www.wdbyte.com/test.git$ java -jar git-app.jar clone test.gitException in thread "main" com.beust.jcommander.ParameterException: 参数 clone 的值必须是 URL 格式 at com.wdbyte.jcommander.v3.UrlParameterValidator.validate(UrlParameterValidator.java:19) at com.beust.jcommander.ParameterDescription.validateParameter(ParameterDescription.java:377) at com.beust.jcommander.ParameterDescription.validateParameter(ParameterDescription.java:344)jcommander 子命令
在使用 git 时,我们经常会使用下面两个命令。
1. git add file1 file2暂存 file1 文件 file2 文件。
2. git commit -m "注释"提交并添加注释。
什么是子命令这是一种很常见的操作,git commit除了可以跟 -m子参数外,还可以跟各种参数,通过 git 帮助文档可以看到。
git commit [-a | --interactive | --patch] [-s] [-v] [-u] [--amend] [--dry-run] [(-c | -C | --fixup | --squash) ] [-F | -m ] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=] [--date= ] [--cleanup= ] [--[no-]status] [-i | -o] [-S[ ]] [--] [ ...]
这种有子参数的情况,我们可以称 commit为 git 的一个子命令,使用 jcommander 如何配置子命令呢?
jcommander 子命令实现我们新增子命令对应的参数类 GitCommandCommit.java.
package com.wdbyte.jcommander;import com.beust.jcommander.Parameter;import com.beust.jcommander.Parameters;/** * git commit -m "desc" * @author https://www.wdbyte.com */@Parameters(commandDescription = "提交文件", commandNames = "commit")public class GitCommandCommit { public static final String COMMAND = "commit"; @Parameter(names = {"-comment", "-m"}, description = "请输入注释", arity = 1, required = true) private String comment; public String getComment() { return comment; }}
代码中使用 @Parameters注解指定了子命令为 commit,同时使用 @Paramete注解指定子参数 -m,同时 -m参数是必须的,使用属性 required = true来指定。
使用 GitCommandCommit:
使用 addCommand添加 Commit命令参数类。
GitCommandOptions gitCommandOptions = new GitCommandOptions();GitCommandCommit commandCommit = new GitCommandCommit();JCommander commander = JCommander.newBuilder() .programName("git-app") .addObject(gitCommandOptions) .addCommand(commandCommit) .build();commander.parse(args);String parsedCommand = commander.getParsedCommand();if ("commit".equals(parsedCommand)) { System.out.println(commandCommit.getComment());}
运行测试:
$ java -jar git-app.jar commit -m "注释一下"注释一下
同上,我们可以添加 add命令对应的参数类:GitCommandAdd.java. 这次我们定义一个 List 类型参数,但是不在属性上指定子参数名称。
package com.wdbyte.jcommander.v5;import java.util.List;import com.beust.jcommander.Parameter;import com.beust.jcommander.Parameters;/** * git add file1 file2 * * @author https://www.wdbyte.com */@Parameters(commandDescription = "暂存文件", commandNames = "add", separators = " ")public class GitCommandAdd { public static final String COMMAND = "add"; @Parameter(description = "暂存文件列表") private Listfiles; public List getFiles() { return files; }}
同样添加到子命令:
JCommander commander = JCommander.newBuilder() .programName("git-app") .addObject(gitCommandOptions) .addCommand(commandCommit) .addCommand(commandAdd) .build();commander.parse(args);if ("add".equals(parsedCommand)) { for (String file : commandAdd.getFiles()) { System.out.println("暂存文件:" + file); }}
运行测试:
$ java -jar git-app.jar add file1.txt file2.txt暂存文件:file1.txt暂存文件:file2.txtjcommander 参数转换
在上面的 GitCommandAdd代码中,add命令传入的都是文件路径,现在是使用 List
首先编写一个转换类 FilePathConverter 用于把入参转换成 Path 类,同时校验文件是否存在
package com.wdbyte.jcommander;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import com.beust.jcommander.IStringConverter;import com.beust.jcommander.ParameterException;/** * * @author https://www.wdbyte.com */public class FilePathConverter implements IStringConverter{ @Override public Path convert(String filePath) { Path path = Paths.get(filePath); if (Files.exists(path)) { return path; } throw new ParameterException(String.format("文件不存在,path:%s", filePath)); }}
通过注解指定转换类:
@Parameter(description = "暂存文件列表", converter = FilePathConverter.class)private Listfiles;
打包测试:
$ java -jar git-app.jar add file1 file2文件不存在,path:file1$ ls -ltotal 12448drwxr-xr-x 2 darcy staff 64B 6 15 21:10 archive-tmpdrwxr-xr-x 3 darcy staff 96B 6 15 21:10 classesdrwxr-xr-x 3 darcy staff 96B 6 15 21:10 generated-sources-rw-r--r-- 1 darcy staff 5.6M 6 16 20:44 git-app.jar$ git-app.jar git-app.jar暂存文件:git-app.jar总体测试
一如既往,文章代码都存放在 Github.com/niumoo/javaNotes.
参考:https://jcommander.org/
关键词:
您可能也感兴趣:
为您推荐
第三方支付流程说明|快讯
某职业技术学院怎么就成上海职业技术学院了?-环球热资讯
6月21日浦银安盛中证沪港深游戏及文化传媒ETF净值下跌5.92%-焦点速读
排行
最近更新
- 使用 JCommander 解析命令行参数
- 跑赢美股丨四巫日天量期权到期,小盘科技股会迎来春天?_天天...
- 微资讯!2023年国家速滑馆端午节开放吗?开闭馆一览
- 【世界独家】2023北京宣武医院端午放假吗?门急诊工作安排公布
- 世界热头条丨Thermaltake推出UX200 SE ARGB散热器:兼顾性...
- 【天天热闻】2023武汉公参民转公招生政策(小学+初中)
- 修出风险?因更换发动机可能引起自燃 12辆涉事路虎被召回 ...
- 每日精选:永登公路段组织新入职职工开展廉洁从业知识测试
- 2023四川科技馆端午节开闭馆时间 今亮点
- 通讯:将核污染水排海是对地球上所有生物的犯罪——日本民众...
- 世界看热讯:2023重庆合川钓鱼城景区端午节门票优惠、游玩攻略
- 龙舟竞渡燃端午 多地举行丰富多彩的活动 环球快资讯
- 河南考古发现距今2000多年的粽子
- 天天新动态:2023顺德博物馆端午节开放时间(附预约入口)
- 这是一场不一般的文艺汇演|环球报道
- 广州疾控:手足口病高峰期已到,出现这些症状可能会短期内发...
- “你点我检”活动已在吉林省全面启动 焦点速读
- 海王英特龙(08329):沈大凯退任非执行董事|天天信息
- 全球速讯:陕西省安委办:端午节期间严格落实安全防范措施
- 2023苏州市中考招生日程安排 天天快报
- 新艺师生闪耀澳门,天山之歌唱响濠江 世界微速讯
- 2023杭州西溪湿地端午龙舟赛游玩全攻略(购票入口+赛事表+出...
- CBA土豪操作出炉!冠军前锋降薪留队:放弃顶薪 为交易周琦铺垫
- 英特尔将出售奥地利芯片公司 IMS 20% 的股份 精彩看点
- 内蒙古新井煤矿事故失联者全部遇难 看热讯
- 焦点速递!美股开盘:三大股指小幅低开 “蔚小理”逆市高开
- 当前观察:618复盘|捂着钱袋子的年轻人求保值,“购金”成流行
- “舞爱金陵”首届城市原创舞蹈作品展演圆满落幕 全球独家
- 阿维塔销量位居前列,品牌口碑逐渐发酵
- 快消息!阿维塔11优势凸显,宝马iX3渐被市场抛弃
今日要闻
- 【世界播资讯】6月21日基金净值:信达睿益鑫享混合最新净值0.9877,跌0.24%
- 每日精选:永登公路段组织新入职职工开展廉洁从业知识测试
- 宋都股份新增冻结3.05亿股股份 延期回复上交所问询函|世界观热点
- 国际绿色零碳节圆满落幕,箭牌家居荣获绿色智造奖,助力“双碳”加速度
- 均普智能: 敬的公司尚未与华为开展直接合作。-资讯
- 天天看热讯:特锐德:公司充电业务有一定的海外布局,但目前处于起步阶段,已出口俄罗斯、中亚、东南亚和欧洲市场
- 世界看热讯:2023重庆合川钓鱼城景区端午节门票优惠、游玩攻略
- oppor15手机官网报价|世界滚动
- 中建四局举办“安全生产月”和“安全生产南沙行”现场观摩会_全球今头条
- 一键查找微公园、建宁驿站、集市(夜市),株洲“便民地图”新上线 环球快报