Spring Shell
Sometimes, in order to facilitate the development and testing of the server, it does not need a beautiful user interface, just use a simple command window. As follows:
Here is a quick, convenient, easy-to-use and simple interactive command window development component Spring Shell Yes, it's in spring ecology again.
Source address
https://gitee.com/wgslucky/spring-shell-demo
Create project
This project uses Eclipse as the IDE of development. Similarly, it can be used to import directly into Idea. The JDK used needs to be version 1.8 or higher, which I tested can also be used on JDK11. Create maven project in eclipse: spring shell demo, and then pom.xml Add the following dependencies to:
<parent> <!-- add to spring boot father pom Dependence, this cannot be less, spring shell Not in the official documents --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.shell</groupId> <artifactId>spring-shell-starter</artifactId> <version>2.0.0.RELEASE</version> </dependency> </dependencies>
Add startup class
@SpringBootApplication public class SpringShellDemo { public static void main(String[] args) { SpringApplication app = new SpringApplication(SpringShellDemo.class); app.setBannerMode(Mode.OFF); app.setWebApplicationType(WebApplicationType.NONE); app.run(args); } }
At this point, the project creation is complete. Now is the time to witness the miracle.
Quickly add a command
Create a command class. The class name can be customized:
@ShellComponent public class MyCommand { @ShellMethod("Connect to server, format: connect ip port") public String connect(String ip,int port) { return String.format("Successfully connected to service:%s:%s", ip,port); } }
Then, run the main method of the project's startup class, and enter the command in the console: It's so simple!!! , just two steps:
- Add a comment on the command class: @ ShellComponent
- Add a comment on the method: @ ShellMethod
Project packaging and running
In the project pom.xml Execute on the directory
mvn clean package
Then the running package is generated under the directory of target: spring-shell-demo-0.0.1-SNAPSHOT.jar You can run this package directly using the following command:
java -jar spring-shell-demo-0.0.1-SNAPSHOT.jar
This way, you can use it at any time outside the IDE.
Use tips
Now you can easily add the interaction command you want. The most important responsibility of the interaction command is to receive the parameters entered by the user. How to execute the command is your business logic. Here are some tips.
Built in commands
Spring Shell contains some common commands, which can be used directly. You can enter help in the running command window to quickly view these commands:
shell:>help AVAILABLE COMMANDS Built-In Commands clear: Clear the shell screen. (Clear screen) exit, quit: Exit the shell. (Exit) help: Display help about available commands. (Help, view all supported commands) script: Read and execute commands from a file. (Read command from file and execute) stacktrace: Display the full stacktrace of the last error. (Display the exception stack. When an error is encountered, use it to quickly view the exception stack.)
Add command description
You can add a description of this command in the @ ShellMethod annotation, so that when you use the help command, you can see these descriptions and understand how to use the command. For example, if you enter help in the command window, you can see:
My Command connect: Connect to server, format: connect ip port
Name of custom command
By default, there is no need to customize the command name. It will use the method name to execute the command to convert the corresponding window command name. If it is more than one word, use separate. For example, the command name of connect method is connect. If the method name is say hello, the command name is say hello If you want to customize the command name, you can add it in the @ ShellMethod annotation:
@ShellMethod(value = "Log in to the server, format: login-server playerId",key = "login-server") public String login(String playerId) { return "Login succeeded:" + playerId; }
Modify prompt
When the spring shell is running, the default command prompt is: shell: > sometimes, it looks awkward, if you can change it to a custom prompt. This can be modified. A new class needs to be added:
@Service public class CustomPromptProvider implements PromptProvider{ @Override public AttributedString getPrompt() { return new AttributedString("xinyues-client:>"); } }
In this way, repackage and run, and the command prompt entered becomes xinyues client: >
Input command parameters with parameter name
When entering a command, if you do not use the command parameter name, the order of the parameters must be the same as that defined in the method. If you want to make the order different, you can add parameter names as follows:
xinyues-client:>connect --port 8888 --ip localhost Successfully connected to service: localhost:8888 xinyues-client:>
The parameter requires two shoulder (- -).
Add default parameter value
Sometimes, some commands can be simplified to use the default value of the parameter if no parameter is entered. As follows:
@ShellMethod("Connect to server, format: connect ip port") public String connectDefault(@ShellOption(defaultValue = "localhost")String ip,@ShellOption(defaultValue = "8080")int port) { return String.format("Successfully connected to service:%s:%s", ip,port); }
A new annotation is used on the parameter: @ ShellOption When using the command, you can directly enter the command name without entering parameters:
xinyues-client:>connect-default Successfully connected to service: localhost:8080 xinyues-client:>
Using array parameters
Sometimes, for the convenience of input, if you don't want to define too many parameter variables, or if the parameter is an array of data, you can use the following method:
@ShellMethod("Add Numbers.") public float add(@ShellOption(arity=3) float[] numbers) { return numbers[0] + numbers[1] + numbers[2]; }
When the input parameter is blank
By default, the spring shell distinguishes multiple parameters by spaces. If a parameter has multiple words and spaces, it cannot be entered directly. You can use double quotation marks or single quotation marks, such as the following command:
@ShellMethod("Prints what has been entered.") public String echo(String what) { return "You said " + what; }
Enter as follows:
shell:>echo Hello You said Hello shell:>echo 'Hello' You said Hello shell:>echo 'Hello World' You said Hello World shell:>echo "Hello World" You said Hello World
You can also use this to avoid escape characters:
shell:>echo "I'm here!" You said I'm here! shell:>echo 'He said "Hi!"' You said He said "Hi!"
Command auto completion function
You can use the tab key to automatically fill in the command name. Similar to the linux command, you can also use the tab to automatically fill in the parameter name.
Command line feed
Sometimes, there are too many command parameters and one line may not be completed. You can add \ "at the end of one line and then enter the command from another line:
shell:>register module --type source --name foo > --uri file:///tmp/bar Successfully registered module 'source:foo'
Shortcut key use
- ctrl + r searches for historically executed commands. Reduce repeated input and improve operation efficiency.
- ctrl + a jump to line header input
- ctrl + e jump to end of line input
- After the up and down arrows input the command name, press the up and down arrows to view the previously entered parameter commands.
Parameter limit
You can use annotations to restrict parameter entry to prevent user input errors, as follows:
@ShellMethod("Change password.") public String changePassword(@Size(min = 8, max = 40) String password) { return "Password successfully set to " + password; }
If the input does not meet the requirements, you will be prompted:
shell:>change-password hello The following constraints were not met: --password string : size must be between 8 and 40 (You passed 'hello')
For more notes to use, see: https://beanvalidation.org/2.0/spec/#builtinconstraints
Command validity detection
Sometimes, there may be some dependency between multiple commands. For example, in such a scenario, the client has a download command, but when using the download command, you must first connect successfully. You can check whether the download command is available as follows:
@ShellComponent public class MyCommands { private boolean connected; @ShellMethod("Connect to the server.") public void connect(String user, String password) { [...] connected = true; } @ShellMethod("Download the nuclear codes.") public void download() { [...] } // Note that the name of the method here is command name + Availability public Availability downloadAvailability() { return connected ? Availability.available() : Availability.unavailable("you are not connected"); } }
In this way, if the user does not use the connect command and directly uses the download command, he will be prompted:
xinyues-client:>download [31mCommand 'download' exists but is not currently available because you are not connected[0m [31mDetails of the error have been omitted. You can use the [1mstacktrace[22m command to print the full stacktrace.[0m xinyues-client:>
The above detection method is that the naming rule must be command name + Availability; another way is to use annotation to specify the detection method name:
@ShellMethod("Download the nuclear codes.") @ShellMethodAvailability("availabilityCheck") public void download() { [...] } public Availability availabilityCheck() { return connected ? Availability.available() : Availability.unavailable("you are not connected"); }