En CLI med Spring Shell

1. Oversikt

Enkelt sagt, Spring Shell-prosjektet gir et interaktivt skall for behandling av kommandoer og bygging av en fullverdig CLI ved hjelp av vårprogrammeringsmodellen.

I denne artikkelen vil vi utforske funksjonene, nøkkelklassene og merknadene, og implementere flere tilpassede kommandoer og tilpasninger.

2. Maven avhengighet

Først må vi legge til vårskall avhengighet til vår pom.xml:

 org.springframework.shell spring-shell 1.2.0.RELEASE 

Den siste versjonen av denne gjenstanden finner du her.

3. Få tilgang til skallet

Det er to måter å få tilgang til skallet i applikasjonene våre.

Den første er å bootstrape skallet i inngangspunktet til applikasjonen vår og la brukeren skrive inn kommandoene:

public static void main (String [] args) kaster IOException {Bootstrap.main (args); }

Det andre er å få en JLineShellComponent og utføre kommandoene programmatisk:

Bootstrap bootstrap = ny Bootstrap (); JLineShellComponent shell = bootstrap.getJLineShellComponent (); shell.executeCommand ("hjelp");

Vi skal bruke den første tilnærmingen siden den passer best for eksemplene i denne artikkelen, men i kildekoden kan du finne testtilfeller som bruker det andre skjemaet.

4. Kommandoer

Det er allerede flere innebygde kommandoer i skallet, som f.eks klar, hjelp, exitosv. som gir standardfunksjonaliteten til alle CLI-er.

Egendefinerte kommandoer kan eksponeres ved å legge til metoder merket med @CliCommand kommentar inne i en vårkomponent som implementerer CommandMarker grensesnitt.

Hvert argument av denne metoden må merkes med a @CliOption merknad, hvis vi ikke klarer dette, vil vi støte på flere feil når vi prøver å utføre kommandoen.

4.1. Legge til kommandoer i skallet

Først må vi la skallet vite hvor kommandoene våre er. For dette krever det filen META-INF / vår / vår-skall-plugin.xml for å være til stede i prosjektet vårt, der, kan vi bruke komponentskanningsfunksjonaliteten til Spring:

Når komponentene er registrert og instantiert av Spring, blir de registrert i skallparseren, og merknadene deres behandles.

La oss lage to enkle kommandoer, en for å hente innholdet i en URL og vise dem, og den andre for å lagre innholdet i en fil:

@Komponent offentlig klasse SimpleCLI implementerer CommandMarker {@CliCommand (verdi = {"web-get", "wg"}) offentlig String webGet (@CliOption (key = "url") String url) {return getContentsOfUrlAsString (url); } @CliCommand (value = {"web-save", "ws"}) offentlig String webSave (@CliOption (key = "url") String url, @CliOption (key = {"out", "file"}) Streng fil) {Strenginnhold = getContentsOfUrlAsString (url); prøv (PrintWriter ut = ny PrintWriter (fil)) {out.write (innhold); } returner "Ferdig."; }}

Merk at vi kan sende mer enn én streng til verdi og nøkkel attributter av @CliCommand og @CliOption henholdsvis dette tillater oss å avsløre flere kommandoer og argumenter som oppfører seg likt.

La oss nå sjekke om alt fungerer som forventet:

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

4.2. Tilgjengelighet av kommandoer

Vi kan bruke @CliAvailabilityIndicator kommentar på en metode som returnerer en boolsk for å endre, ved kjøretid, hvis en kommando skulle bli utsatt for skallet.

La oss først lage en metode for å endre tilgjengeligheten av web-lagre kommando:

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

La oss nå lage en kommando for å endre adminEnableExecuted variabel:

@CliCommand (verdi = "admin-aktivere") offentlig streng adminEnable () {adminEnableExecuted = true; returner "Admin-kommandoer aktivert."; }

Til slutt, la oss bekrefte det:

spring-shell> web-save --url //www.google.com --out contents.txt Kommandoen 'web-save --url //www.google.com --out contents.txt' ble funnet, men er ikke for øyeblikket tilgjengelig (skriv 'hjelp', deretter ENTER for å lære mer om denne kommandoen) spring-shell> admin-aktivere Admin-kommandoer aktivert. spring-shell> web-save --url //www.google.com --out contents.txt Ferdig.

4.3. Nødvendige argumenter

Som standard er alle kommandoargumenter valgfrie. Imidlertid kan vi gjøre dem nødvendige med påbudt, bindende attributt til @CliOption kommentar:

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

Nå kan vi teste at hvis vi ikke introduserer det, resulterer det i en feil:

spring-shell> web-save --url //www.google.com Du bør angi alternativet (--out) for denne kommandoen

4.4. Standardargumenter

En tom nøkkel verdi for en @CliOption gjør argumentet til standard. Der vil vi motta verdiene introdusert i skallet som ikke er en del av noe navngitt argument:

@CliOption (key = {"", "url"})

La oss nå sjekke at det fungerer som forventet:

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

4.5. Hjelpe brukere

@CliCommand og @CliOption merknader gir en hjelp attributt som lar oss veilede brukerne når vi bruker den innebygde hjelp kommandoen eller når du faner for å få automatisk fullføring.

La oss endre vår web-get for å legge til tilpassede hjelpemeldinger:

@CliCommand (// ... help = "Viser innholdet i en URL") offentlig String webGet (@CliOption (// ... help = "URL hvis innhold vil bli vist.") String url) {//. ..}

Nå kan brukeren vite nøyaktig hva kommandoen vår gjør:

spring-shell> help web-get Keyword: web-get Keyword: wg Beskrivelse: Viser innholdet i en URL. Søkeord: ** standard ** Søkeord: url Hjelp: URL hvis innhold vil bli vist. Obligatorisk: false Standard hvis spesifisert: '__NULL__' Standard hvis ikke spesifisert: '__NULL__' * web-get - Viser innholdet i en URL. * wg - Viser innholdet i en URL.

5. Tilpasning

Det er tre måter å tilpasse skallet ved å implementere BannerProvider, PromptProvider og HistoryFileNameProvider grensesnitt, alle med standardimplementeringer som allerede er gitt.

Vi må også bruke @Rekkefølge kommentar for å tillate leverandørene våre å gå foran disse implementeringene.

La oss lage et nytt banner for å begynne vår tilpasning:

@Component @Order (Ordered.HIGHEST_PRECEDENCE) offentlig klasse SimpleBannerProvider utvider 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 ("Versjon:") .append (this.getVersion ()); retur buf.toString (); } offentlig String getVersion () {return "1.0.1"; } public String getWelcomeMessage () {return "Velkommen til Baeldung CLI"; } public String getProviderName () {return "Baeldung Banner"; }}

Merk at vi også kan endre versjonsnummer og velkomstmelding.

La oss endre ledeteksten:

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

Til slutt, la oss endre navnet på historikkfilen:

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

Historikkfilen registrerer alle kommandoer som er utført i skallet, og blir lagt sammen med applikasjonen vår.

Med alt på plass kan vi ringe skallet vårt og se det i aksjon:

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

6. Omformere

Så langt har vi bare brukt enkle typer som argumenter for kommandoene våre. Vanlige typer som Heltall, Dato, Enum, Fil, etc., har en standardkonverter allerede registrert.

Ved å implementere Konverter grensesnitt, kan vi også legge til omformerne for å motta egendefinerte objekter.

La oss lage en omformer som kan transformere en String inn i en URL:

@Komponent offentlig klasse SimpleURLConverter implementerer Converter {public URL convertFromText (String value, Class requiredType, String optionContext) {return new URL (value); } offentlig boolsk getAllPossibleValues ​​(Listefullførelser, Class requiredType, String existingData, String optionContext, MethodTarget target) {return false; } offentlige boolske støtter (Class requiredType, String optionContext) {return URL.class.isAssignableFrom (requiredType); }}

Til slutt, la oss endre vår web-get og web-lagre kommandoer:

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

Som du kanskje har gjettet, oppfører kommandoene seg det samme.

7. Konklusjon

I denne artikkelen tok vi en kort titt på kjernefunksjonene i Spring Shell-prosjektet. Vi var i stand til å bidra med kommandoene våre og tilpasse skallet med leverandørene våre, vi endret tilgjengeligheten av kommandoer i henhold til forskjellige kjøretidsforhold og opprettet en enkel type omformer.

Komplett kildekode for denne artikkelen finner du på GitHub.


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