<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用 JCommander 解析命令行參數(shù)

          共 9625字,需瀏覽 20分鐘

           ·

          2023-06-20 20:24

          前言

          如果你想構(gòu)建一個(gè)支持命令行參數(shù)的程序,那么 jcommander 非常適合你,jcommander 是一個(gè)只有幾十 kb 的 Java 命令行參數(shù)解析工具,可以通過(guò)注解的方式快速實(shí)現(xiàn)命令行參數(shù)解析。

          這篇教程會(huì)通過(guò)介紹 jcommadner ,快速的創(chuàng)建一個(gè)命令行程序,最后支持的命令參數(shù)功能如下圖。

          這個(gè)命令行工具仿照 git 操作命令,主要提供了如下功能命令:

          1. 1.?git-app.jar -help?查看命令幫助信息。

          2. 2.?git-app.jar -version?查看當(dāng)前版本號(hào)。

          3. 3.?git-app.jar clone http://xxxx?通過(guò) URL 克隆一個(gè)倉(cāng)庫(kù)。

          4. 4.?git-app.jar add file1 file2?暫存 file1 文件 file2 文件。

          5. 5.?git-app.jar commit -m "注釋"?提交并添加注釋。

          jcommander 引入

          截止文章編寫(xiě)時(shí)間,最新版本如下:


          <dependency>
          ????<groupId>com.beustgroupId>
          ????<artifactId>jcommanderartifactId>
          ????<version>1.82version>
          dependency>

          jcommander 參數(shù)綁定

          命令行解析中,參數(shù)解析與綁定是最實(shí)用的一個(gè)場(chǎng)景,jcommander 使用?Parameter?注解進(jìn)行參數(shù)綁定。我們定義一個(gè)?GitCommandOptions.java?類(lèi)來(lái)測(cè)試參數(shù)綁定。

          package?com.wdbyte.jcommander.v1;

          import?com.beust.jcommander.Parameter;

          /**
          ?*?@author?https://www.wdbyte.com
          ?*/

          public?class?GitCommandOptions?{
          ????@Parameter(names?=?{"clone"},
          ????????description?=?"克隆遠(yuǎn)程倉(cāng)庫(kù)數(shù)據(jù)")

          ????private?String?cloneUrl;

          ????public?String?getCloneUrl()?{
          ????????return?cloneUrl;
          ????}
          }

          使用 jcommander 結(jié)合 GitCommandOptions 來(lái)解析參數(shù)。

          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());
          ????}
          }

          打包后可以執(zhí)行命令參數(shù):

          $?java?-jar?git-app.jar?clone?http://www.wdbyte.com/test.git
          clone?http://www.wdbyte.com/test.git

          這里是一個(gè)字符串參數(shù),需要在命令中輸出參數(shù)值,對(duì)于 boolean 類(lèi)型的參數(shù),不需要傳值,有命令即為 true 值。

          參數(shù)名稱

          @Parameter?注解中的?names?屬性可以定義參數(shù)的名稱。且可以指定多個(gè)參數(shù)名稱,讓我再添加?version?參數(shù)和?help?參數(shù),同時(shí)設(shè)置參數(shù)別名。這兩個(gè)參數(shù)是 boolean 類(lèi)型。

          @Parameter(names?=?{"help",?"-help",?"-h"},
          ????description?=?"查看幫助信息",
          ????help?=?true)

          private?boolean?help;

          @Parameter(names?=?{"version",?"-version",?"-v"},
          ????description?=?"顯示當(dāng)前版本號(hào)")

          private?boolean?version?=?false;

          參數(shù)限制

          clone?參數(shù)可以接受一個(gè)要克隆的 URL 鏈接,但是正常情況下只需要一個(gè) URL 鏈接。可以通過(guò)?arity = 1?進(jìn)行限制。

          @Parameter(names?=?{"clone"},
          ????description?=?"克隆遠(yuǎn)程倉(cāng)庫(kù)數(shù)據(jù)",
          ????arity?=?1)

          private?String?cloneUrl;

          幫助信息

          使用?usage()?參數(shù)可以打印命令幫助信息。

          GitCommandOptions?gitCommandOptions?=?new?GitCommandOptions();
          JCommander?commander?=?JCommander.newBuilder()
          ????.addObject(gitCommandOptions)
          ????.build();
          commander.parse(args);
          //?打印幫助信息
          commander.usage();

          運(yùn)行輸出幫助信息:

          $?java?-jar?git-app.jar
          Usage:??[options]
          ??Options:
          ????clone
          ??????克隆遠(yuǎn)程倉(cāng)庫(kù)數(shù)據(jù)
          ????help,?-help,?-h
          ??????查看幫助信息
          ????version,?-version,?-v
          ??????顯示當(dāng)前版本號(hào)
          ??????Default:?false

          雖然正確的輸出了幫助信息,但是其中有?main class?這段,是因?yàn)槲覀儧](méi)有指定項(xiàng)目名稱,我們指定項(xiàng)目名稱為?git-app

          JCommander?commander?=?JCommander.newBuilder()
          ????????????.programName("git-app")
          ????????????.addObject(gitCommandOptions)
          ????????????.build();

          參數(shù)排序

          在幫助信息中,如果想要自定義參數(shù)順序,可以通過(guò)?order =?來(lái)排序,數(shù)字越小越靠前。

          @Parameter(names?=?{"version",?"-version",?"-v"},
          ????description?=?"顯示當(dāng)前版本號(hào)",
          ????order?=?2)

          private?boolean?version?=?false;

          參數(shù)綁定完整測(cè)試

          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?=?"克隆遠(yuǎn)程倉(cāng)庫(kù)數(shù)據(jù)",
          ????????order?=?3,
          ????????arity?=?1)

          ????private?String?cloneUrl;

          ????@Parameter(names?=?{"version",?"-version",?"-v"},
          ????????description?=?"顯示當(dāng)前版本號(hào)",
          ????????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());
          ????????}
          ????}
          }

          運(yùn)行測(cè)試:

          jcommander 參數(shù)驗(yàn)證

          在上面的例子中, 假設(shè) clone 命令傳入的參數(shù)必須是一個(gè) URL,那么我們就要進(jìn)行參數(shù)驗(yàn)證,jcommander 也提供了特有的參數(shù)驗(yàn)證方式。

          1. 1.?編寫(xiě)參數(shù)驗(yàn)證類(lèi),需要實(shí)現(xiàn)?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("參數(shù)?"?+?key?+?"?的值必須是?URL?格式");
            ????????}
            ????}
            }
          2. 2.?clone?參數(shù)指定驗(yàn)證類(lèi)。

            @Parameter(names?=?{"clone"},
            ????description?=?"克隆遠(yuǎn)程倉(cāng)庫(kù)數(shù)據(jù)",
            ????validateWith?=?UrlParameterValidator.class,
            ????order?=?3,
            ????arity?=?1)

            private?String?cloneUrl;

          運(yùn)行測(cè)試:

          $?java?-jar?git-app.jar?clone?https://www.wdbyte.com/test.git
          clone?https://www.wdbyte.com/test.git

          $?
          java?-jar?git-app.jar?clone?test.git
          Exception?in?thread?"main"?com.beust.jcommander.ParameterException:?參數(shù)?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 時(shí),我們經(jīng)常會(huì)使用下面兩個(gè)命令。

          1. 1.?git add file1 file2?暫存 file1 文件 file2 文件。

          2. 2.?git commit -m "注釋"?提交并添加注釋。

          什么是子命令

          這是一種很常見(jiàn)的操作,git commit?除了可以跟?-m?子參數(shù)外,還可以跟各種參數(shù),通過(guò) 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[]]?[--]?[...]

          這種有子參數(shù)的情況,我們可以稱?commit?為 git 的一個(gè)子命令,使用 jcommander 如何配置子命令呢?

          jcommander 子命令實(shí)現(xiàn)

          我們新增子命令對(duì)應(yīng)的參數(shù)類(lèi) 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?=?"請(qǐng)輸入注釋",
          ????????arity?=?1,
          ????????required?=?true)

          ????private?String?comment;

          ????public?String?getComment()?{
          ????????return?comment;
          ????}
          }

          代碼中使用?@Parameters?注解指定了子命令為?commit,同時(shí)使用?@Paramete?注解指定子參數(shù)?-m,同時(shí)?-m?參數(shù)是必須的,使用屬性?required = true?來(lái)指定。

          使用 GitCommandCommit:

          使用?addCommand?添加?Commit?命令參數(shù)類(lèi)。

          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());
          }

          運(yùn)行測(cè)試:

          $?java?-jar?git-app.jar?commit?-m?'注釋一下'
          注釋一下

          同上,我們可以添加?add?命令對(duì)應(yīng)的參數(shù)類(lèi):GitCommandAdd.java. 這次我們定義一個(gè) List 類(lèi)型參數(shù),但是不在屬性上指定子參數(shù)名稱。

          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?List?files;

          ????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);
          ????}
          }

          運(yùn)行測(cè)試:

          $?java?-jar?git-app.jar?add?file1.txt?file2.txt
          暫存文件:file1.txt
          暫存文件:file2.txt

          jcommander 參數(shù)轉(zhuǎn)換

          在上面的?GitCommandAdd?代碼中,add?命令傳入的都是文件路徑,現(xiàn)在是使用?List?來(lái)接收入?yún)ⅲǔG闆r想我們可能需要直接轉(zhuǎn)換成方便操作的類(lèi)型,如 File 或者 Path,這該如何方面的轉(zhuǎn)換呢,jcommander 也提供了方便轉(zhuǎn)換類(lèi)。

          首先編寫(xiě)一個(gè)轉(zhuǎn)換類(lèi) FilePathConverter 用于把入?yún)⑥D(zhuǎn)換成 Path 類(lèi),同時(shí)校驗(yàn)文件是否存在

          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));
          ????}
          }

          通過(guò)注解指定轉(zhuǎn)換類(lèi):

          @Parameter(description?=?"暫存文件列表",?converter?=?FilePathConverter.class)
          private?List?files;

          打包測(cè)試:

          $?java?-jar?git-app.jar?add?file1?file2
          文件不存在,path:file1

          $?
          ls?-l
          total?12448
          drwxr-xr-x??2?darcy??staff????64B??6?15?21:10?archive-tmp
          drwxr-xr-x??3?darcy??staff????96B??6?15?21:10?classes
          drwxr-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

          總體測(cè)試

          一如既往,文章代碼都存放在?Github.com/niumoo/javaNotes.

          參考:https://jcommander.org/

          瀏覽 65
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  zzjizzji | 狠久久| 操操片| 啊啊黄色视频国产视频 | 先锋影院亚洲无码 |