摘要:入門中把解釋參數(shù)分為三種狀態(tài),分別是定義解釋和詢問交互。如果入?yún)⒚钆c實(shí)例對(duì)應(yīng)不上就會(huì)拋出解析異常。查詢交互可以對(duì)入?yún)⒚钸M(jìn)行判斷解析,例如可以查詢是否存在某個(gè)選項(xiàng),以及獲取這個(gè)選項(xiàng)的值。
前言
以前寫過一些命令行程序,在需要帶參數(shù)的時(shí)候都是自己來判斷args,導(dǎo)致程序光解析args都占了好大一堆,而且解析代碼也不美觀。
偶然間發(fā)現(xiàn)了apache公共庫(kù)中的cli庫(kù),在這里分享給大家。
commons-cli中把解釋參數(shù)分為三種狀態(tài),分別是定義、解釋和詢問交互。
接下來,我以一個(gè)例子做一下說明:
maven庫(kù):
commons-cli commons-cli 1.3.1
import org.apache.commons.cli.*; public class CLI { public static void main(String[] args) throws ParseException { //定義 Options options = new Options(); options.addOption("h",false,"list help");//false代表不強(qiáng)制有 options.addOption("t",true,"set time on system"); //解析 //1.3.1中已經(jīng)棄用針對(duì)不同格式入?yún)?duì)應(yīng)的解析器 //CommandLineParser parser = new PosixParser(); CommandLineParser parser = new DefaultParser(); CommandLine cmd = parser.parse(options,args); //查詢交互 //你的程序應(yīng)當(dāng)寫在這里,從這里啟動(dòng) if (cmd.hasOption("h")){ String formatstr = "CLI cli test"; HelpFormatter hf = new HelpFormatter(); hf.printHelp(formatstr, "", options, ""); return; } if (cmd.hasOption("t")){ System.out.printf("system time has setted %s ",cmd.getOptionValue("t")); return; } System.out.println("error"); } }
在另一個(gè)類中做一下測(cè)試
String argss[]={"-t 1000"}; CLI.main(argss);
結(jié)果是:
system time has setted 1000
String argss[]={"-h"}; CLI.main(argss);
結(jié)果是:
usage: CLI cli test
-h list help
-t
好啦,入門就到這里了。
代碼結(jié)構(gòu)分析包組織結(jié)構(gòu):
commons-cli-1.3.1.jar
org.apache.commons.cli
在cli包中,包含了所有的類,包括定義,解析,查詢交互和Exception
類的關(guān)系結(jié)構(gòu)圖如下
定義在定義這一部分,最重要的類是Option,Option類中定義了一個(gè)基本的選項(xiàng),例如-t xxx ,是否為必選項(xiàng),該命令的解釋等等。
Option重寫了很多構(gòu)造函數(shù),但是最終都調(diào)用下面這個(gè)構(gòu)造函數(shù):
public Option(String opt, String longOpt, boolean hasArg, String description) throws IllegalArgumentException { //寫這個(gè)代碼的人以前應(yīng)該是寫C++的。。。 // 判斷短選項(xiàng)是否包含非法字符,如果包含拋出異常 OptionValidator.validateOption(opt); //短選項(xiàng) this.opt = opt; //長(zhǎng)選項(xiàng) this.longOpt = longOpt; // 是否是必要選項(xiàng) if (hasArg) { this.numberOfArgs = 1; } //選項(xiàng)描述 this.description = description; }
OptionsGroup類中包含了許多個(gè)Option,并可以對(duì)多個(gè)Option進(jìn)行一些處理。其實(shí)現(xiàn)是采用一個(gè)HashMap來存儲(chǔ)Option的,key是Option中的長(zhǎng)選項(xiàng)或者短選項(xiàng)的第一個(gè)字符,如果短選項(xiàng)存在,則優(yōu)先選擇短選項(xiàng)。
OptionGroup類還包含了一個(gè)組描述和組是否必須存在,相當(dāng)于對(duì)一群Option的群組操作。
Options類是被解析的對(duì)象,使用者可以在Options實(shí)例中直接添加命令,也可以添加Option實(shí)例,也可以添加OptionGroup實(shí)例。
其addOption方法最終調(diào)用了其重寫的一個(gè)方法:
public Options addOption(Option opt) { String key = opt.getKey(); // add it to the long option list if (opt.hasLongOpt()) { longOpts.put(opt.getLongOpt(), opt); } // if the option is required add it to the required list if (opt.isRequired()) { if (requiredOpts.contains(key)) { requiredOpts.remove(requiredOpts.indexOf(key)); } requiredOpts.add(key); } shortOpts.put(key, opt); return this; }
添加GroupOption方法如下:
public Options addOptionGroup(OptionGroup group) { if (group.isRequired()) { requiredOpts.add(group); } for (Option option : group.getOptions()) { // an Option cannot be required if it is in an // OptionGroup, either the group is required or // nothing is required option.setRequired(false); addOption(option); optionGroups.put(option.getKey(), group); } return this; }解析
接下來就是CommandLineParser接口,在1.3.1版本中取消了Parser抽象類,GnuParser、BasicParser、PosixParser類,取而代之的是DefaultParser類。DefaultParser類提供了對(duì)Options實(shí)例的解析,即對(duì)入?yún)⒚詈蚈ptions實(shí)例之間對(duì)應(yīng)關(guān)系的解析,返回的類是CommandLine。如果入?yún)⒚钆cOptions實(shí)例對(duì)應(yīng)不上就會(huì)拋出解析異常。
DefaultParser類解析方法最基本的方法是handleToken(String token),token是每一個(gè)入?yún)⒆址?。這個(gè)方法會(huì)在解析錯(cuò)誤的時(shí)候拋出解析異常。
查詢交互CommandLine可以對(duì)入?yún)⒚钸M(jìn)行判斷解析,例如可以查詢是否存在某個(gè)選項(xiàng),以及獲取這個(gè)選項(xiàng)的值。
總結(jié)cli包還是相當(dāng)簡(jiǎn)單的,大家也可以自己看一看commons庫(kù)的源碼。
更多文章:http://blog.gavinzh.com
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/65114.html
摘要:包執(zhí)行時(shí)傳參的使用姿勢(shì)雖說我們現(xiàn)在大多不太直接使用包運(yùn)行方式,目前比較主流的是將自己的服務(wù)丟在某個(gè)容器中如,等運(yùn)行,比如我之前所屬的電商公司,就是將項(xiàng)目打包為包,丟到容器中運(yùn)行的在使用時(shí),可能會(huì)出現(xiàn)直接打包一個(gè)可執(zhí)行的,然后運(yùn)行,這種時(shí)候, showImg(https://segmentfault.com/img/remote/1460000015684728); jar包執(zhí)行時(shí)傳參的...
摘要:經(jīng)過年時(shí)間的發(fā)展,到目前為止,最新穩(wěn)定版為版本。的發(fā)展剛出生的時(shí)候,引起了很多開源社區(qū)的關(guān)注,并且也有個(gè)人和企業(yè)開始嘗試使用。通過項(xiàng)目搭建過程來對(duì)比的差異和優(yōu)勢(shì)。當(dāng)然它的作用不僅于此,后續(xù)會(huì)逐步揭開它的真實(shí)面目。而和就相當(dāng)于當(dāng)年的和的關(guān)系。 要了解Spring Boot的發(fā)展背景,還得從2004年Spring ...
摘要:本文要來分享給大家程序員最常用的日志框架組件。沒有基礎(chǔ)的同學(xué)也不要著急,這套教程覆蓋了目前所有的日志框架,只要你學(xué),就一定用得到,先收藏,以備不時(shí)之需。 作為一名Java程序員,我們開發(fā)了很多Java應(yīng)用程序,包括桌面應(yīng)用、WEB應(yīng)用以及移動(dòng)應(yīng)用。然而日志系統(tǒng)是一個(gè)成熟Java應(yīng)用所必不可少的。在開發(fā)和調(diào)試階段,日志可以幫...
摘要:五六月份推薦集合查看最新的請(qǐng)點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語(yǔ)。葉上初陽(yáng)乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長(zhǎng)安旅。五月漁郎相憶否。小楫輕舟,夢(mèng)入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請(qǐng)::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...
閱讀 783·2021-10-09 09:58
閱讀 644·2021-08-27 16:24
閱讀 1729·2019-08-30 14:15
閱讀 2389·2019-08-30 11:04
閱讀 2076·2019-08-29 18:43
閱讀 2171·2019-08-29 15:20
閱讀 2722·2019-08-26 12:20
閱讀 1620·2019-08-26 11:44