En CLI med Spring Shell

1. Oversigt

Kort sagt, Spring Shell-projektet giver en interaktiv shell til behandling af kommandoer og opbygning af en komplet CLI ved hjælp af Spring-programmeringsmodellen.

I denne artikel undersøger vi dens funktioner, nøgleklasser og kommentarer og implementerer flere brugerdefinerede kommandoer og tilpasninger.

2. Maven-afhængighed

Først skal vi tilføje forårskal afhængighed af vores pom.xml:

 org.springframework.shell spring-shell 1.2.0.RELEASE 

Den seneste version af denne artefakt kan findes her.

3. Adgang til skallen

Der er to hovedmåder at få adgang til skallen i vores applikationer.

Den første er at bootstrappe skallen i indgangsstedet for vores applikation og lade brugeren indtaste kommandoerne:

offentlig statisk ugyldig hoved (String [] args) kaster IOException {Bootstrap.main (args); }

Den anden er at opnå en JLineShellComponent og udføre kommandoerne programmatisk:

Bootstrap bootstrap = ny Bootstrap (); JLineShellComponent shell = bootstrap.getJLineShellComponent (); shell.executeCommand ("hjælp");

Vi skal bruge den første tilgang, da den er bedst egnet til eksemplerne i denne artikel, men i kildekoden kan du finde testsager, der bruger den anden form.

4. Kommandoer

Der er allerede flere indbyggede kommandoer i skallen, såsom klar, Hjælp, Afslutosv., der leverer standardfunktionaliteten for hver CLI.

Brugerdefinerede kommandoer kan eksponeres ved at tilføje metoder markeret med @CliCommand kommentar inde i en fjederkomponent, der implementerer CommandMarker interface.

Hvert argument af denne metode skal markeres med a @CliOption kommentar, hvis vi ikke gør dette, støder vi på flere fejl, når vi prøver at udføre kommandoen.

4.1. Tilføjelse af kommandoer til skallen

Først skal vi lade skallen vide, hvor vores kommandoer er. Til dette kræver det filen META-INF / spring / spring-shell-plugin.xml for at være til stede i vores projekt, der, kan vi bruge komponentscanningsfunktionaliteten i Spring:

Når komponenterne er registreret og instantificeret af Spring, registreres de i shell-parseren, og deres annoteringer behandles.

Lad os oprette to enkle kommandoer, den ene til at få fat i indholdet af en URL og vise dem, og den anden for at gemme indholdet i en fil:

@Komponent offentlig klasse SimpleCLI implementerer CommandMarker {@CliCommand (værdi = {"web-get", "wg"}) offentlig String webGet (@CliOption (key = "url") String url) {return getContentsOfUrlAsString (url); } @CliCommand (værdi = {"web-save", "ws"}) offentlig String webSave (@CliOption (key = "url") String url, @CliOption (key = {"out", "file"}) Streng fil) {String indhold = getContentsOfUrlAsString (url); prøv (PrintWriter out = ny PrintWriter (fil)) {out.write (indhold); } returner "Udført."; }}

Bemærk, at vi kan videregive mere end en streng til værdi og nøgle egenskaber af @CliCommand og @CliOption henholdsvis dette tillader os at udsætte flere kommandoer og argumenter, der opfører sig det samme.

Lad os nu kontrollere, om alt fungerer som forventet:

spring-shell> web-get --url //www.google.com web-save --url //www.google.com --out contents.txt Udført.

4.2. Tilgængelighed af kommandoer

Vi kan bruge @CliAvailabilityIndicator anmærkning om en metode, der returnerer en boolsk for at ændre ved kørsel, hvis en kommando skulle blive udsat for skallen.

Lad os først oprette en metode til at ændre tilgængeligheden af web-gem kommando:

privat boolsk adminEnableExecuted = false; @CliAvailabilityIndicator (value = "web-save") offentlig boolsk isAdminEnabled () {return adminEnableExecuted; }

Lad os nu oprette en kommando til at ændre adminEnableExecuted variabel:

@CliCommand (værdi = "admin-aktiv") offentlig streng adminEnable () {adminEnableExecuted = true; returner "Admin-kommandoer aktiveret."; }

Lad os endelig kontrollere det:

spring-shell> web-save --url //www.google.com --out contents.txt Kommandoen 'web-save --url //www.google.com --out contents.txt' blev fundet, men er ikke aktuelt tilgængelig (skriv 'hjælp' og derefter ENTER for at lære mere om denne kommando) spring-shell> admin-aktiver Admin-kommandoer aktiveret. spring-shell> web-save --url //www.google.com --out contents.txt Udført.

4.3. Påkrævede argumenter

Som standard er alle kommandoargumenter valgfri. Vi kan dog stille dem påkrævet med obligatorisk attribut for @CliOption kommentar:

@CliOption (key = {"out", "file"}, obligatorisk = true)

Nu kan vi teste, at hvis vi ikke introducerer det, resulterer det i en fejl:

spring-shell> web-save --url //www.google.com Du skal angive indstilling (--out) for denne kommando

4.4. Standardargumenter

En tom nøgle værdi for en @CliOption gør dette argument til standard. Der modtager vi de værdier, der er introduceret i skallen, som ikke er en del af et navngivet argument:

@CliOption (nøgle = {"", "url"})

Lad os nu kontrollere, at det fungerer som forventet:

spring-shell> web-get //www.google.com 

4.5. Hjælpe brugere

@CliCommand og @CliOption annoteringer giver en Hjælp attribut, der giver os mulighed for at guide vores brugere, når vi bruger den indbyggede Hjælp kommando eller når du faner for at få automatisk udfyldning.

Lad os ændre vores web-get for at tilføje tilpassede hjælpemeddelelser:

@CliCommand (// ... help = "Viser indholdet af en URL") offentlig String webGet (@CliOption (// ... help = "URL hvis indhold vil blive vist.") String url) {//. ..}

Nu kan brugeren vide nøjagtigt, hvad vores kommando gør:

spring-shell> help web-get Keyword: web-get Keyword: wg Beskrivelse: Viser indholdet af en URL. Søgeord: ** standard ** Søgeord: url Hjælp: URL, hvis indhold vises. Obligatorisk: falsk Standard, hvis angivet: '__NULL__' Standard, hvis ikke specificeret: '__NULL__' * web-get - Viser indholdet af en URL. * wg - Viser indholdet af en URL.

5. Tilpasning

Der er tre måder at tilpasse skallen ved at implementere Bannerudbyder, PromptProvider og HistoryFileNameProvider grænseflader, alle med standardimplementeringer, der allerede er leveret.

Vi skal også bruge @Bestille annotering for at give vores udbydere forrang over disse implementeringer.

Lad os oprette et nyt banner for at begynde vores tilpasning:

@Component @Order (Ordered.HIGHEST_PRECEDENCE) offentlig klasse SimpleBannerProvider udvider DefaultBannerProvider {public String getBanner () {StringBuffer buf = new StringBuffer (); buf.append ("==========================================") .append (OsUtils .LINE_SEPARATOR); buf.append ("* Baeldung Shell *") .append (OsUtils.LINE_SEPARATOR); buf.append ("===========================================") .append (OsUtils .LINE_SEPARATOR); buf.append ("Version:") .append (this.getVersion ()); returnere buf.toString (); } offentlig streng getVersion () {return "1.0.1"; } offentlig String getWelcomeMessage () {return "Velkommen til Baeldung CLI"; } public String getProviderName () {return "Baeldung Banner"; }}

Bemærk, at vi også kan ændre versionsnummer og velkomstbesked.

Lad os nu ændre prompten:

@Component @Order (Ordered.HIGHEST_PRECEDENCE) offentlig klasse SimplePromptProvider udvider DefaultPromptProvider {public String getPrompt () {return "baeldung-shell"; } public String getProviderName () {return "Baeldung Prompt"; }}

Lad os endelig ændre navnet på historikfilen:

@Component @Order (Ordered.HIGHEST_PRECEDENCE) offentlig klasse SimpleHistoryFileNameProvider udvider DefaultHistoryFileNameProvider {public String getHistoryFileName () {return "baeldung-shell.log"; } public String getProviderName () {return "Baeldung History"; }}

Historikfilen registrerer alle kommandoer, der udføres i skallen, og placeres ved siden af ​​vores applikation.

Med alt på plads kan vi kalde vores shell og se den i aktion:

========================================= * Baeldung Shell * ======= ================================= Version: 1.0.1 Velkommen til Baeldung CLI baeldung-shell>

6. Konvertere

Indtil videre har vi kun brugt enkle typer som argumenter for vores kommandoer. Almindelige typer såsom Heltal, Dato, Enum, Filosv. har en standardkonverter allerede registreret.

Ved at implementere Konverter interface, kan vi også tilføje vores konvertere for at modtage brugerdefinerede objekter.

Lad os oprette en konverter, der kan transformere en Snor ind i en URL:

@Komponent offentlig klasse SimpleURLConverter implementerer Converter {public URL convertFromText (String value, Class requiredType, String optionContext) {return new URL (value); } public boolean getAllPossibleValues ​​(Listeafslutninger, Class requiredType, String existingData, String optionContext, MethodTarget target) {return false; } offentlige boolske understøttelser (klasse krævet type, streng optionContext) {return URL.class.isAssignableFrom (requiredType); }}

Lad os endelig ændre vores web-get og web-gem kommandoer:

public String webSave (... URL url) {// ...} public String webSave (... URL url) {// ...}

Som du måske har gættet, opfører kommandoerne det samme.

7. Konklusion

I denne artikel havde vi et kort kig på kernefunktionerne i Spring Shell-projektet. Vi var i stand til at bidrage med vores kommandoer og tilpasse shell med vores udbydere, vi ændrede tilgængeligheden af ​​kommandoer i henhold til forskellige runtime-forhold og skabte en simpel type konverter.

Komplet kildekode til denne artikel kan findes på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found