Анализиране на параметрите на командния ред с авиокомпания

1. Въведение

В този урок ще представим Airline - управлявана от анотации библиотека Java за изграждане на интерфейси на командния ред (CLI).

2. Сценарий

Когато изграждате приложение за команден ред, естествено е да създадете прост интерфейс, който да позволи на потребителя да формира изхода при необходимост. Почти всеки е играл с Git CLI и може да се свърже с това колко е мощен, но прост. Уви, малко инструменти са полезни при изграждането на такъв интерфейс.

Авиокомпанията има за цел да намали стандартния код, обикновено свързан с CLI в Java , тъй като най-често поведението може да се постигне с анотации и нулев потребителски код.

Ще приложим малка Java програма, която ще използва функционалностите на Airline, за да имитира общ CLI. Той ще изложи потребителски команди за настройка на нашата програмна конфигурация, като дефиниране на URL адреса на базата данни, идентификационните данни и многословието на регистратора. Също така ще се потопим под повърхността на нашата библиотека и ще използваме повече от нейните основи, за да проучим дали тя може да се справи с някаква сложност.

3. Настройка

За да започнем, нека добавим зависимостта на авиокомпанията към нашия pom.xm l:

 com.github.rvesse airline 2.7.2  

4. Прост CLI

Нека създадем нашата входна точка за приложението - класът CommandLine :

@Cli(name = "baeldung-cli", description = "Baeldung Airline Tutorial", defaultCommand = Help.class) public class CommandLine { public static void main(String[] args) { Cli cli = new Cli(CommandLine.class); Runnable cmd = cli.parse(args); cmd.run(); } }

Чрез проста анотация @Cli дефинирахме командата по подразбиране, която ще се изпълнява в нашето приложение - командата Help .

Класът за помощ идва като част от библиотеката на Airline и излага команда за помощ по подразбиране, използвайки опции -h или –help .

Точно така, основната настройка е направена.

5. Първата ни команда

Нека изпълним първата си команда, прост клас LoggingCommand, който ще контролира многословието на нашите регистрационни файлове. Ще коментираме класа с @Command, за да гарантираме, че правилната команда се прилага, когато потребителят извиква setup-log :

@Command(name = "setup-log", description = "Setup our log") public class LoggingCommand implements Runnable { @Inject private HelpOption help; @Option(name = { "-v", "--verbose" }, description = "Set log verbosity on/off") private boolean verbose = false; @Override public void run() { if (!help.showHelpIfRequested()) System.out.println("Verbosity: " + verbose); } } }

Нека разгледаме по-отблизо нашата примерна команда.

Първо, ние сме задали описание, така че нашият помощник, благодарение на инжектирането, ще покаже нашите командни опции при поискване.

Тогава ние обявен за булева променлива, многословно , и то с пояснение @Option да му се даде име, описание, а също така е псевдоним -V / -verbose да представлява нашата опция за команден ред за контрол на детайлност.

И накрая, вътре в метода на изпълнение , инструктирахме нашата команда да спре, когато потребителят поиска помощ.

Дотук добре. Сега трябва да добавим нашата нова команда към основния интерфейс, като променим анотацията @ Cli :

@Cli(name = "baeldung-cli", description = "Baeldung Airline Tutorial", defaultCommand = Help.class, commands = { LoggingCommand.class, Help.class }) public class CommandLine { public static void main(String[] args) { Cli cli = new Cli(CommandLine.class); Runnable cmd = cli.parse(args); cmd.run(); } } 

Сега, ако предадем setup-log -v на нашата програма, тя ще изпълни нашата логика.

6. Ограничения и други

Видяхме как Airline генерира CLI безупречно, но ... има още!

Можем да посочим ограничения (или ограничения) за нашите параметри за обработка на разрешени стойности, изисквания или зависимости и др.

Ще създадем клас DatabaseSetupCommand , който ще отговори на командата setup-db ; както направихме по-рано, но ще добавим малко подправка.

Първо, ще поискаме типа база данни, приемайки само 3 валидни стойности чрез @AllowedRawValues :

@AllowedRawValues(allowedValues = { "mysql", "postgresql", "mongodb" }) @Option(type = OptionType.COMMAND, name = {"-d", "--database"}, description = "Type of RDBMS.", title = "RDBMS type: mysql|postgresql|mongodb") protected String rdbmsMode;

Когато използват връзка с база данни, без никакво съмнение, потребителите трябва да предоставят крайна точка и някои идентификационни данни за достъп до нея. Ще оставим CLI да се справи с това чрез един ( URL режим) или повече параметри ( хостов режим ). За това ще използваме анотацията @MutuallyExclusiveWith , маркирайки всеки параметър със същия етикет:

@Option(type = OptionType.COMMAND, name = {"--rdbms:url", "--url"}, description = "URL to use for connection to RDBMS.", title = "RDBMS URL") @MutuallyExclusiveWith(tag="mode") @Pattern(pattern="^(//.*):(d*)(.*)u=(.*)&p=(.*)") protected String rdbmsUrl = ""; @Option(type = OptionType.COMMAND, name = {"--rdbms:host", "--host"}, description = "Host to use for connection to RDBMS.", title = "RDBMS host") @MutuallyExclusiveWith(tag="mode") protected String rdbmsHost = ""; 

Имайте предвид, че използвахме декоратора @Pattern , който ни помага да дефинираме формата на URL низа.

Ако разгледаме документацията на проекта, ще намерим други ценни инструменти за обработка на изисквания, събития, допустими стойности, конкретни случаи и други, което ни позволява да дефинираме нашите персонализирани правила .

И накрая, ако потребителят е избрал режима на хост, трябва да го помолим да предостави своите идентификационни данни. По този начин една опция зависи от друга. Можем да постигнем това поведение с анотацията @RequiredOnlyIf :

@RequiredOnlyIf(names={"--rdbms:host", "--host"}) @Option(type = OptionType.COMMAND, name = {"--rdbms:user", "-u", "--user"}, description = "User for login to RDBMS.", title = "RDBMS user") protected String rdbmsUser; @RequiredOnlyIf(names={"--rdbms:host", "--host"}) @Option(type = OptionType.COMMAND, name = {"--rdbms:password", "--password"}, description = "Password for login to RDBMS.", title = "RDBMS password") protected String rdbmsPassword; 

Ами ако трябва да използваме някои драйвери за обработка на DB връзката? И също така, да предположим, че трябва да получим повече от една стойност в един параметър. Можем просто да променим типа опция на OptionType.ARGUMENTS или - още по-добре - да приемем списък със стойности:

@Option(type = OptionType.COMMAND, name = {"--driver", "--jars"}, description = "List of drivers", title = "--driver  --driver ") protected List jars = new ArrayList();

Сега, нека не забравяме да добавим командата за настройка на базата данни към нашия основен клас. В противен случай няма да е налице в CLI.

7. Бягай

Успяхме! Завършихме проекта си и вече можем да го изпълним.

Както се очакваше, без да преминават никакви параметри, Помощ се извиква:

$ baeldung-cli usage: baeldung-cli  [  ] Commands are: help Display help information setup-db Setup our database setup-log Setup our log See 'baeldung-cli help ' for more information on a specific command.

Ако вместо това изпълним setup-log –help , получаваме:

$ baeldung-cli setup-log --help NAME baeldung-cli setup-log - Setup our log SYNOPSIS baeldung-cli setup-log [ -h  ] [ -v  ] OPTIONS -h, --help Display help information -v, --verbose Set log verbosity on/off

И накрая, предоставянето на параметри на тези команди ще изпълни правилната бизнес логика.

8. Заключение

В тази статия сме изградили прост, но мощен интерфейс на командния ред с много малко кодиране.

Библиотеката на Airline, с мощните си функционалности, опростява CLI, предоставяйки ни обща, чиста и многократно използваема инфраструктура . Това ни позволява, разработчиците, да се концентрираме върху нашата бизнес логика, вместо да отделяме време за проектиране на това, което трябва да бъде тривиално.

Както винаги, кодът може да бъде намерен в GitHub.