我已经使用spring boot web starter创建了restfull web应用程序,运行良好。我可以通过urls访问它。
但我有要求创建控制台命令,可以计算和存储在后端的一些值。我希望能够手动或通过bash脚本运行控制台命令。
我找不到任何关于如何在spring boot web应用程序中集成spring-shell项目的文档。
此外,在spring boot starter https://start.spring.io/中也没有选择spring-shell依赖项的选项
1) webapp和控制台是否需要是两个独立的应用程序,并且需要分别部署?
2)是否可以在同一个应用中部署web应用和运行控制台命令?
3)在shell和web应用程序之间共享公共代码(模型、服务、实体、业务逻辑)的最佳方法是什么?
有没有人能帮个忙?
发布于 2016-09-05 19:22:01
这里有两个选项:
(1)从命令行调用的Rest API
您可以创建一个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脚本中。
spring (2)使用
--remote-shell(不推荐使用)
虽然它主要用于监视/管理目的,但您也可以使用spring-boot-remote-shell。
Dependencies
您需要以下依赖项才能启用远程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 (来源:https://stackoverflow.com/a/24300534/641627):
BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
MyController myController = beanFactory.getBean(MyController.class);启动SpringBootApp
使用类路径上的spring- Boot -remote-shell,Spring Boot应用程序监听端口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)如何使用参数和选项(在评论中回答问题)
参数
要使用参数,可以查看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进行
一个完整的例子
以下内容包括:
带有参数的constructor;
代码:
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发布于 2016-09-05 19:07:40
听起来您在这里有两个截然不同的用例:运行计划任务和手动运行命令。据我所知,Spring Shell不是Boot生态系统的一部分。您可以在Boot Web应用程序外部编写Spring Shell应用程序,但它不会嵌入其中。至少从我的经验来看。
对于计划任务的第一种情况,您应该查看Spring's Scheduler。您应该能够配置包含Task Scheduler的Spring应用程序(Boot或normal)。然后,您可以配置可以调度的任务,让调度器来完成工作。
对于手动执行命令,这里有几个选项。如果您使用Spring Shell,假设它在Spring Boot进程外部的自己的进程中运行。您需要使用远程方法调用技术(例如,RMI、REST等)将Shell应用程序调用到Boot应用程序(假设这是您希望工作的位置)。
Spring Shell的替代方案是将远程shell嵌入到Boot应用程序中。实际上,您可以使用SSH连接到Boot应用程序并以与Spring Shell类似的方式定义命令。好处是,这与Boot应用程序处于相同的过程中。因此,您可以插入Task Scheduler并手动运行与计划相同的任务。如果您想手动取消正在调度的相同任务,这可能是一个很好的选择。远程控制台的Doco是here。
希望这能有所帮助
https://stackoverflow.com/questions/39329017
复制相似问题