java 如何使用spring shell在spring boot web应用程序中构建控制台命令?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39329017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 04:16:45  来源:igfitidea点击:

how to build console command in spring boot web application using spring shell?

javaspringspring-bootspring-webspring-shell

提问by vishal

I have created restfull web application using spring boot web starter which works well. I am able to access it through urls.

我已经使用 spring boot web starter 创建了restfull web 应用程序,它运行良好。我可以通过网址访问它。

But I have requirement to create console command which can compute and store some values at the backend. I want to be able to run console command manually or through bash script.

但是我需要创建控制台命令,该命令可以在后端计算和存储一些值。我希望能够手动或通过 bash 脚本运行控制台命令。

I could not find any documentation on how to integrate spring-shell project in spring boot web application.

我找不到任何关于如何在 spring boot web 应用程序中集成 spring-shell 项目的文档。

Also there is no option to choose spring-shell dependency in spring boot starter https://start.spring.io/

在 spring boot starter https://start.spring.io/ 中也没有选择 spring-shell 依赖项的选项

1) Do webapp and console need to be two separate applications and I need to deploy them separately ?

1) webapp 和控制台是否需要是两个独立的应用程序,我需要分别部署它们吗?

2) Is it possible to deploy web app and run console commands in the same app ?

2) 是否可以在同一个应用程序中部署 Web 应用程序并运行控制台命令?

3) What is the best approach to share common code (model, services, entities, business logic) between shell and web applications ?

3) 在 shell 和 web 应用程序之间共享公共代码(模型、服务、实体、业务逻辑)的最佳方法是什么?

Can anyone please help on this ?

任何人都可以帮忙吗?

采纳答案by alexbt

Here's 2 options:

这里有 2 个选项:

(1) Rest API called from the command line

(1) 从命令行调用的Rest API

You could create a Spring @RestController, which you then call 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"
    }
    '

You can easily embed this in a nice shell script.

您可以轻松地将其嵌入到一个漂亮的 shell 脚本中。

(2) Use spring-boot-remote-shell (deprecated)

(2) 使用 spring-boot-remote-shell (已弃用)

Though it is mainly for monitoring/administration purposes, you may use the spring-boot-remote-shellfor that.

虽然它主要用于监控/管理目的,但您可以使用spring-boot-remote-shell来实现。

Dependencies

依赖关系

You need the following dependencies to enable the remote-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 script:

常规脚本

Add the following script in src/main/resources/custom.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"
    }
}

To get a hold of a Spring bean from this groovy script (source: https://stackoverflow.com/a/24300534/641627):

要从这个 groovy 脚本中获取 Spring bean(来源:https: //stackoverflow.com/a/24300534/641627):

BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
MyController myController = beanFactory.getBean(MyController.class);

Launch your SpringBootApp

启动您的 SpringBootApp

With spring-boot-remote-shell on the classpath, the Spring Boot Application listens on port 5000 (by default). You can now do this:

使用类路径上的 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

帮助

You can type helpto see the list of available commands:

您可以键入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 

Call our custom command

调用我们的自定义命令

Our custom command is listed (the fourth from the top), you can call it:

我们的自定义命令已列出(从上数第四个),您可以调用它:

> custom
Hello

So, essentially, your crontab would do a telnet 5000and execute custom

所以,本质上,你的 crontab 会做一个telnet 5000并执行custom

(3) How to use arguments and options (to answer question in comments)

(3) 如何使用参数和选项(在评论中回答问题)

Arguments

参数

To use arguments, you can take a look at the 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

Sub-command (or options)

子命令(或选项)

Still from their 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

The last command executes:

最后一条命令执行:

  • the command jdbc
  • with subcommand connect
  • and the argument jdbc:derby:memory:EmbeddedDB;create=true
  • 命令 jdbc
  • 带子命令 connect
  • 和论点 jdbc:derby:memory:EmbeddedDB;create=true

A Complete example

一个完整的例子

The following contains:

以下内容包含:

  • a constructor;
  • a command with arguments;
  • a spring managed bean;
  • a subcommand with arguments.
  • 一个构造函数;
  • 带参数的命令;
  • 一个春季管理的豆子;
  • 带参数的子命令。

The code:

代码:

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

回答by EdH

It sounds like you have two distinct use cases here: running scheduled tasks, and running commands manually. From my understanding, Spring Shell isn't part of the Boot ecosystem. You can write a Spring Shell application that is external to your Boot Web app, but it's not going to embed within it. At least from my experience.

听起来您在这里有两个不同的用例:运行计划任务和手动运行命令。根据我的理解,Spring Shell 不是 Boot 生态系统的一部分。您可以编写一个位于 Boot Web 应用程序外部的 Spring Shell 应用程序,但它不会嵌入其中。至少从我的经验来看。

For the first case of scheduled tasks, you should look at Spring's Scheduler. You should be able to configure a Spring application (Boot or normal) that has a Task Scheduler within it. Then you can configure your Tasks that can be scheduled, letting the scheduler do the work.

对于计划任务的第一种情况,您应该查看Spring 的 Scheduler。您应该能够配置一个包含任务计划程序的 Spring 应用程序(启动或普通)。然后,您可以配置可以调度的任务,让调度程序完成工作。

For manually executing the commands, you do have a few options here. If you use Spring Shell, assume it's running in its own process, external to the Spring Boot process. You would need to have the Shell app call into the Boot application (presuming that's where you want to work to occur) using remote method invocation technologies (eg, RMI, REST, etc).

对于手动执行命令,您在这里有几个选项。如果您使用 Spring Shell,请假设它在自己的进程中运行,位于 Spring Boot 进程的外部。您需要使用远程方法调用技术(例如,RMI、REST 等)让 Shell 应用程序调用引导应用程序(假设这是您想要工作的地方)。

An alternative to Spring Shell is to embed a remote shell into your Boot application. Essentially, you can use SSH to connect to your Boot application and define commands in a similar fashion as Spring Shell. The benefit is that this is in the same process as the Boot application. So you can inject the Task Scheduler and run the same Tasks manually as are scheduled. This might be a good option if you want to manually kick of the same Tasks are being scheduled. Doco for the remote console is here.

Spring Shell 的替代方法是将远程 shell 嵌入到您的 Boot 应用程序中。本质上,您可以使用 SSH 连接到 Boot 应用程序并以与 Spring Shell 类似的方式定义命令。好处是这与引导应用程序在同一进程中。因此,您可以注入任务计划程序并按照计划手动运行相同的任务。如果您想手动启动正在安排的相同任务,这可能是一个不错的选择。远程控制台的 Doco 在这里

Hope this helps

希望这可以帮助