как создать консольную команду в веб-приложении spring boot с помощью spring shell?
Я создал restfull веб-приложение с помощью spring boot web starter, который хорошо работает. Я могу получить доступ к нему через URL-адреса.
но у меня есть требование создать консольную команду, которая может вычислять и хранить некоторые значения на бэкэнде. Я хочу иметь возможность запускать консольную команду вручную или через скрипт bash.
Я не смог найти никакой документации о том, как интегрировать проект spring-shell в веб-приложение spring boot.
также нет возможность выбора зависимости spring-shell в spring boot starter https://start.spring.io/
1) должны ли webapp и консоль быть двумя отдельными приложениями, и мне нужно развернуть их отдельно ?
2) Можно ли развернуть веб-приложение и запустить консольные команды в одном приложении ?
3) каков наилучший подход для совместного использования общего кода (модели, служб, сущностей, бизнес-логики) между оболочкой и веб-приложениями ?
может кто-нибудь пожалуйста, помогите в этом ?
2 ответов
вот 2 варианта:
(1) REST API вызывается из командной строки
вы могли бы создать пружину @RestController
, который вы затем вызываете из командной строки ?
curl -X POST -i -H "Content-type: application/json" -c cookies.txt -X POST http://hostname:8080/service -d '
{
"field":"value",
"field2":"value2"
}
'
вы можете легко встроить это в хороший сценарий оболочки.
(2) использовать spring-boot-remote-shell (устаревший)
хотя это в основном для целей мониторинга/администрирования может использовать spring-boot-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:
добавьте следующий скрипт в 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 (source: 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) Как использовать аргументы и опции (чтобы ответить на вопрос в комментариях)
Аргументы
использовать аргументы, вы можете взглянуть на документация:
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
суб-команды (или опции)
все от документация:
@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
полный пример
содержится следующее:
- конструктор;
- команда с аргументами;
- весной удалось Боб;
- подкоманда с аргументами.
код:
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 Shell не является частью экосистемы загрузки. Вы можете написать приложение Spring Shell, которое является внешним для вашего загрузочного веб-приложения, но оно не будет встраиваться в него. По крайней мере, по моему опыту.
для первого случая запланированных задач, вы должны посмотреть планировщик весны. Вы должны иметь возможность настроить пружину приложение (загрузочное или обычное), в котором есть планировщик задач. Затем вы можете настроить задачи, которые могут быть запланированы, позволяя планировщику выполнять работу.
для ручного выполнения команд, у вас есть несколько вариантов здесь. Если вы используете Spring Shell, предположим,что он работает в своем собственном процессе, внешнем для процесса загрузки Spring. Вам нужно будет вызвать приложение оболочки в загрузочное приложение (предполагая, что именно там вы хотите работать), используя удаленный вызов метода технологии (например, RMI, REST и т. д.).
альтернативой Spring Shell является внедрение удаленной оболочки в ваше загрузочное приложение. По сути, вы можете использовать SSH для подключения к загрузочному приложению и определять команды аналогично Spring Shell. Благо это в том же процессе в качестве приложения загрузки. Таким образом, Вы можете ввести планировщик задач и запустить те же задачи вручную, что и запланировано. Это может быть хорошим вариантом, если вы хотите вручную пипец же Задачи планируются. Doco для удаленной консоли -здесь.
надеюсь, что это помогает