如何使用 spring shell 在 spring 引导 Web 应用程序中构建控制台命令?
how to build console command in spring boot web application using spring shell?
我已经使用 spring boot web starter 创建了 restfull web 应用程序,效果很好。我可以通过网址访问它。
但是我需要创建控制台命令,它可以在后端计算和存储一些值。我希望能够手动或通过 bash 脚本 运行 控制台命令。
我找不到任何关于如何在 spring 引导 Web 应用程序中集成 spring-shell 项目的文档。
此外,在 spring 引导启动器中没有选择 spring-shell 依赖项的选项 https://start.spring.io/
1) webapp 和console 是否需要是两个独立的应用程序并且我需要单独部署它们?
2) 是否可以在同一应用中部署网络应用和 运行 控制台命令?
3) 在 shell 和 Web 应用程序之间共享通用代码(模型、服务、实体、业务逻辑)的最佳方法是什么?
任何人都可以帮忙吗?
听起来您在这里有两个不同的用例:运行ning 计划任务和 运行ning 手动命令。据我了解,Spring Shell 不是 Boot 生态系统的一部分。您可以编写一个 Spring Shell 应用程序,该应用程序位于您的 Boot Web 应用程序外部,但不会嵌入其中。至少从我的经验来看。
第一种情况的定时任务,你应该看看Spring's Scheduler。您应该能够配置一个 Spring 应用程序(启动或正常),其中有一个任务计划程序。然后你可以配置你的任务可以被调度,让调度器来完成工作。
对于手动执行命令,您在这里有几个选项。如果您使用 Spring Shell,假设它在 运行 自己的进程中,在 Spring 引导进程之外。您需要使用远程方法调用技术(例如,RMI、REST 等)将 Shell 应用程序调用到启动应用程序(假设您希望在此处工作)。
Spring Shell 的替代方法是将远程 shell 嵌入到您的启动应用程序中。本质上,您可以使用 SSH 连接到您的 Boot 应用程序并以类似于 Spring Shell 的方式定义命令。好处是这与启动应用程序处于同一进程中。因此,您可以按计划手动注入任务计划程序和 运行 相同的任务。如果您想手动踢出正在安排的相同任务,这可能是一个不错的选择。远程控制台的 Doco 是 here.
希望对您有所帮助
这里有 2 个选项:
(1) Rest API called from the command line
您可以创建一个 Spring @RestController
,然后从命令行调用它 ?
curl -X POST -i -H "Content-type: application/json" -c cookies.txt -X POST http://hostname:8080/service -d '
{
"field":"value",
"field2":"value2"
}
'
您可以轻松地将它嵌入到一个不错的 shell 脚本中。
(2) Use spring-boot-remote-shell (deprecated)
虽然它主要用于 monitoring/administration 目的,但您可以为此使用 spring-boot-remote-shell。
依赖关系
您需要以下依赖项才能启用远程-shell:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-remote-shell</artifactId>
</dependency>
<dependency>
<groupId>org.crsh</groupId>
<artifactId>crsh.shell.telnet</artifactId>
<version>1.3.0-beta2</version>
</dependency>
Groovy 脚本:
在src/main/resources/custom.groovy
中添加以下脚本:
package commands
import org.crsh.cli.Command
import org.crsh.cli.Usage
import org.crsh.command.InvocationContext
class custom {
@Usage("Custom command")
@Command
def main(InvocationContext context) {
return "Hello"
}
}
从这个 groovy 脚本中获取 Spring bean(来源:):
BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
MyController myController = beanFactory.getBean(MyController.class);
启动您的 SpringBootApp
在类路径上使用 spring-boot-remote-shell,Spring 引导应用程序侦听端口 5000(默认)。
您现在可以这样做:
$ telnet localhost 5000
Trying ::1...
Connected to localhost.
Escape character is '^]'.
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.3.5.RELEASE)
帮助
您可以键入 help
以查看可用命令列表:
NAME DESCRIPTION
autoconfig Display auto configuration report from ApplicationContext
beans Display beans in ApplicationContext
cron manages the cron plugin
custom Custom command
dashboard
egrep search file(s) for lines that match a pattern
endpoint Invoke actuator endpoints
env display the term env
filter A filter for a stream of map
help provides basic help
java various java language commands
jmx Java Management Extensions
jul java.util.logging commands
jvm JVM informations
less opposite of more
log logging commands
mail interact with emails
man format and display the on-line manual pages
metrics Display metrics provided by Spring Boot
shell shell related command
sleep sleep for some time
sort Sort a map
system vm system properties commands
thread JVM thread commands
调用我们的自定义命令
我们的自定义命令已列出(从上数第四个),您可以调用它:
> custom
Hello
所以,基本上,您的 crontab 会执行 telnet 5000
并执行 custom
(3) How to use arguments and options (to answer question in comments)
参数
要使用参数,您可以查看 documentation:
class date {
@Usage("show the current time")
@Command
Object main(
@Usage("the time format")
@Option(names=["f","format"])
String format) {
if (format == null)
format = "EEE MMM d HH:mm:ss z yyyy";
def date = new Date();
return date.format(format);
}
}
% date -h
% usage: date [-h | --help] [-f | --format]
% [-h | --help] command usage
% [-f | --format] the time format
% date -f yyyyMMdd
子命令(或选项)
仍然来自他们的 documentation:
@Usage("JDBC connection")
class jdbc {
@Usage("connect to database with a JDBC connection string")
@Command
public String connect(
@Usage("The username")
@Option(names=["u","username"])
String user,
@Usage("The password")
@Option(names=["p","password"])
String password,
@Usage("The extra properties")
@Option(names=["properties"])
Properties properties,
@Usage("The connection string")
@Argument
String connectionString) {
...
}
@Usage("close the current connection")
@Command
public String close() {
...
}
}
% jdbc connect jdbc:derby:memory:EmbeddedDB;create=true
最后执行的命令:
- 命令
jdbc
- 使用子命令
connect
- 和参数
jdbc:derby:memory:EmbeddedDB;create=true
一个完整的例子
以下包含:
- 一个构造函数;
- 带参数的命令;
- 一个spring托管bean;
- 带参数的子命令。
代码:
package commands
import org.crsh.cli.Command
import org.crsh.cli.Usage
import org.crsh.command.InvocationContext
import org.springframework.beans.factory.BeanFactory
import com.alexbt.goodies.MyBean
class SayMessage {
String message;
SayMessage(){
this.message = "Hello";
}
@Usage("Default command")
@Command
def main(InvocationContext context, @Usage("A Parameter") @Option(names=["p","param"]) String param) {
BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
MyBean bean = beanFactory.getBean(MyBean.class);
return message + " " + bean.getValue() + " " + param;
}
@Usage("Hi subcommand")
@Command
def hi(InvocationContext context, @Usage("A Parameter") @Option(names=["p","param"]) String param) {
BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
MyBean bean = beanFactory.getBean(MyBean.class);
return "Hi " + bean.getValue() + " " + param;
}
}
> saymsg -p Johnny
> Hello my friend Johnny
> saymsg hi -p Johnny
> Hi my friend Johnny
我已经使用 spring boot web starter 创建了 restfull web 应用程序,效果很好。我可以通过网址访问它。
但是我需要创建控制台命令,它可以在后端计算和存储一些值。我希望能够手动或通过 bash 脚本 运行 控制台命令。
我找不到任何关于如何在 spring 引导 Web 应用程序中集成 spring-shell 项目的文档。
此外,在 spring 引导启动器中没有选择 spring-shell 依赖项的选项 https://start.spring.io/
1) webapp 和console 是否需要是两个独立的应用程序并且我需要单独部署它们?
2) 是否可以在同一应用中部署网络应用和 运行 控制台命令?
3) 在 shell 和 Web 应用程序之间共享通用代码(模型、服务、实体、业务逻辑)的最佳方法是什么?
任何人都可以帮忙吗?
听起来您在这里有两个不同的用例:运行ning 计划任务和 运行ning 手动命令。据我了解,Spring Shell 不是 Boot 生态系统的一部分。您可以编写一个 Spring Shell 应用程序,该应用程序位于您的 Boot Web 应用程序外部,但不会嵌入其中。至少从我的经验来看。
第一种情况的定时任务,你应该看看Spring's Scheduler。您应该能够配置一个 Spring 应用程序(启动或正常),其中有一个任务计划程序。然后你可以配置你的任务可以被调度,让调度器来完成工作。
对于手动执行命令,您在这里有几个选项。如果您使用 Spring Shell,假设它在 运行 自己的进程中,在 Spring 引导进程之外。您需要使用远程方法调用技术(例如,RMI、REST 等)将 Shell 应用程序调用到启动应用程序(假设您希望在此处工作)。
Spring Shell 的替代方法是将远程 shell 嵌入到您的启动应用程序中。本质上,您可以使用 SSH 连接到您的 Boot 应用程序并以类似于 Spring Shell 的方式定义命令。好处是这与启动应用程序处于同一进程中。因此,您可以按计划手动注入任务计划程序和 运行 相同的任务。如果您想手动踢出正在安排的相同任务,这可能是一个不错的选择。远程控制台的 Doco 是 here.
希望对您有所帮助
这里有 2 个选项:
(1) Rest API called from the command line
您可以创建一个 Spring @RestController
,然后从命令行调用它 ?
curl -X POST -i -H "Content-type: application/json" -c cookies.txt -X POST http://hostname:8080/service -d '
{
"field":"value",
"field2":"value2"
}
'
您可以轻松地将它嵌入到一个不错的 shell 脚本中。
(2) Use spring-boot-remote-shell (deprecated)
虽然它主要用于 monitoring/administration 目的,但您可以为此使用 spring-boot-remote-shell。
依赖关系
您需要以下依赖项才能启用远程-shell:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-remote-shell</artifactId>
</dependency>
<dependency>
<groupId>org.crsh</groupId>
<artifactId>crsh.shell.telnet</artifactId>
<version>1.3.0-beta2</version>
</dependency>
Groovy 脚本:
在src/main/resources/custom.groovy
中添加以下脚本:
package commands
import org.crsh.cli.Command
import org.crsh.cli.Usage
import org.crsh.command.InvocationContext
class custom {
@Usage("Custom command")
@Command
def main(InvocationContext context) {
return "Hello"
}
}
从这个 groovy 脚本中获取 Spring bean(来源:):
BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
MyController myController = beanFactory.getBean(MyController.class);
启动您的 SpringBootApp
在类路径上使用 spring-boot-remote-shell,Spring 引导应用程序侦听端口 5000(默认)。 您现在可以这样做:
$ telnet localhost 5000
Trying ::1...
Connected to localhost.
Escape character is '^]'.
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.3.5.RELEASE)
帮助
您可以键入 help
以查看可用命令列表:
NAME DESCRIPTION
autoconfig Display auto configuration report from ApplicationContext
beans Display beans in ApplicationContext
cron manages the cron plugin
custom Custom command
dashboard
egrep search file(s) for lines that match a pattern
endpoint Invoke actuator endpoints
env display the term env
filter A filter for a stream of map
help provides basic help
java various java language commands
jmx Java Management Extensions
jul java.util.logging commands
jvm JVM informations
less opposite of more
log logging commands
mail interact with emails
man format and display the on-line manual pages
metrics Display metrics provided by Spring Boot
shell shell related command
sleep sleep for some time
sort Sort a map
system vm system properties commands
thread JVM thread commands
调用我们的自定义命令
我们的自定义命令已列出(从上数第四个),您可以调用它:
> custom
Hello
所以,基本上,您的 crontab 会执行 telnet 5000
并执行 custom
(3) How to use arguments and options (to answer question in comments)
参数
要使用参数,您可以查看 documentation:
class date {
@Usage("show the current time")
@Command
Object main(
@Usage("the time format")
@Option(names=["f","format"])
String format) {
if (format == null)
format = "EEE MMM d HH:mm:ss z yyyy";
def date = new Date();
return date.format(format);
}
}
% date -h
% usage: date [-h | --help] [-f | --format]
% [-h | --help] command usage
% [-f | --format] the time format
% date -f yyyyMMdd
子命令(或选项)
仍然来自他们的 documentation:
@Usage("JDBC connection")
class jdbc {
@Usage("connect to database with a JDBC connection string")
@Command
public String connect(
@Usage("The username")
@Option(names=["u","username"])
String user,
@Usage("The password")
@Option(names=["p","password"])
String password,
@Usage("The extra properties")
@Option(names=["properties"])
Properties properties,
@Usage("The connection string")
@Argument
String connectionString) {
...
}
@Usage("close the current connection")
@Command
public String close() {
...
}
}
% jdbc connect jdbc:derby:memory:EmbeddedDB;create=true
最后执行的命令:
- 命令
jdbc
- 使用子命令
connect
- 和参数
jdbc:derby:memory:EmbeddedDB;create=true
一个完整的例子
以下包含:
- 一个构造函数;
- 带参数的命令;
- 一个spring托管bean;
- 带参数的子命令。
代码:
package commands
import org.crsh.cli.Command
import org.crsh.cli.Usage
import org.crsh.command.InvocationContext
import org.springframework.beans.factory.BeanFactory
import com.alexbt.goodies.MyBean
class SayMessage {
String message;
SayMessage(){
this.message = "Hello";
}
@Usage("Default command")
@Command
def main(InvocationContext context, @Usage("A Parameter") @Option(names=["p","param"]) String param) {
BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
MyBean bean = beanFactory.getBean(MyBean.class);
return message + " " + bean.getValue() + " " + param;
}
@Usage("Hi subcommand")
@Command
def hi(InvocationContext context, @Usage("A Parameter") @Option(names=["p","param"]) String param) {
BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
MyBean bean = beanFactory.getBean(MyBean.class);
return "Hi " + bean.getValue() + " " + param;
}
}
> saymsg -p Johnny
> Hello my friend Johnny
> saymsg hi -p Johnny
> Hi my friend Johnny