- Вопрос или проблема
- именованный аргумент
- неименованный аргумент
- неименованный аргумент с дополнительной булевой опцией
- именованный аргумент с дополнительной булевой опцией
- Ответ или решение
- Понимание работы Spring Shell
- Основы и аннотации
- Применение именованных и неименованных аргументов
- Именованные аргументы
- Неименованные аргументы
- Примеры и объяснения ошибок
- Заключение
Вопрос или проблема
Я использую spring-shell 3.3.3 в spring boot и у меня есть следующий код:
@Command
public class ExperimentCommand {
@Command(command = "experiment", description = "Загружает множество файлов из папки")
@SuppressWarnings("java:S107")
public String experiment(
@Option(longNames = "path", description = "Путь к директории с файлами для обработки", required = true, arity = OptionArity.EXACTLY_ONE) String path,
@Option(longNames = "async", description = "Использовать асинхронные запросы на уровне HTTP", arity = OptionArity.ZERO, defaultValue = "false") boolean async) {
return """
путь %s
асинхронный %s"""
.formatted(path, async);
}
}
Я не совсем понимаю, когда опция должна быть именованной, а когда нет. У меня есть следующие примеры:
именованный аргумент
java .. experiment --path ABC
< путь ABC
< асинхронный false
это работает, как и ожидалось
неименованный аргумент
java .. experiment ABC
< путь ABC
< асинхронный false
Это тоже работает, но мне интересно, как spring-shell понимает, что неименованный аргумент именно путь (особенно, если есть несколько поддерживаемых аргументов)
неименованный аргумент с дополнительной булевой опцией
java .. experiment --async ABC
< Слишком много аргументов для опции 'async', требует максимум '0'
< Неверное значение опции 'ABC', причина 'Не удалось преобразовать из типа [java.lang.String] в тип [boolean] для значения [ABC]'
< Отсутствует обязательная опция '--path', Путь к директории с файлами для обработки
Поскольку --async
имеет arity=OptionArity.ZERO
, как получается, что следующий аргумент интерпретируется как булевый?
именованный аргумент с дополнительной булевой опцией
java .. experiment --async --path ABC
< путь ABC
< асинхронный true
С точки зрения опции --async
это то же самое, что и предыдущий вызов. Почему это работает и дополнительное булевое значение не ожидается, а в примере 3 возникла ошибка?
Ответ или решение
Понимание работы Spring Shell
Spring Shell — это мощный инструмент для создания командных интерфейсов в приложениях на основе Spring Boot. В данном ответе мы подробно рассмотрим, как работает Spring Shell, используя код вашего примера, и поясним, когда необходимо использовать именованные и неименованные аргументы.
Основы и аннотации
В вашем коде имеется класс команд, помеченный аннотацией @Command
. Это говорит Spring Shell, что данный класс определяет команды, которые могут быть вызваны через командную строку. Команда experiment
принимает два аргумента:
- path: обязательный параметр, указывающий путь к директории с файлами.
- async: необязательный параметр, который может быть представлен в виде флага (true/false).
Применение именованных и неименованных аргументов
Spring Shell позволяет использовать как именованные, так и неименованные аргументы.
Именованные аргументы
Именованные аргументы передаются с помощью ключей, например:
java .. experiment --path ABC
В этом случае Spring Shell четко понимает, что аргумент ABC
должен соответствовать параметру path
. Параметр async
, имеющий значение по умолчанию false
, автоматически будет восприниматься как таковой.
Неименованные аргументы
Неименованные аргументы позволяют более гибко использовать команду. Например:
java .. experiment ABC
Здесь ABC
будет интерпретироваться как path
, поскольку он является первым аргументом после названия команды. Это поведение поддерживается Spring Shell, который присваивает значения аргументам по порядку.
Примеры и объяснения ошибок
- Неименованный аргумент с неправильным флагом:
java .. experiment --async ABC
Здесь вы получаете ошибку, потому что передали ABC
вместо просто указания --async
. Параметр async
имеет arity=OptionArity.ZERO
, что означает, что он не ожидает какого-либо значения. Вы передали лишний аргумент ABC
, что привело к ошибке конвертации типов.
- Правильное использование имени с флагом:
java .. experiment --async --path ABC
Здесь --async
принимается как флаг (true), а --path
— как обязательный параметр, и вызов выполняется без ошибок. Spring Shell справляется с заданием, поскольку параметр async
не требует значений, а path
получает значение ABC
.
Заключение
Различие между именованными и неименованными аргументами в Spring Shell предоставляет возможность гибко конфигурировать команды. Важно помнить о порядке аргументов и значениях, ожидаемых определенными параметрами. Ваш пример показывает базовые принципы работы с командной оболочкой Spring, что значительно упрощает разработку командных интерфейсов в приложениях на базе Spring Boot. С обращением внимания на правильную структуру и логику передачи аргументов можно избежать распространенных ошибок и сделать интерфейс более удобным и интуитивным для пользователей.
Если у вас остались вопросы или требуется дополнительная поддержка, не стесняйтесь обращаться за разъяснениями!