Понимание того, как работает 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 принимает два аргумента:

  1. path: обязательный параметр, указывающий путь к директории с файлами.
  2. async: необязательный параметр, который может быть представлен в виде флага (true/false).

Применение именованных и неименованных аргументов

Spring Shell позволяет использовать как именованные, так и неименованные аргументы.

Именованные аргументы

Именованные аргументы передаются с помощью ключей, например:

java .. experiment --path ABC

В этом случае Spring Shell четко понимает, что аргумент ABC должен соответствовать параметру path. Параметр async, имеющий значение по умолчанию false, автоматически будет восприниматься как таковой.

Неименованные аргументы

Неименованные аргументы позволяют более гибко использовать команду. Например:

java .. experiment ABC

Здесь ABC будет интерпретироваться как path, поскольку он является первым аргументом после названия команды. Это поведение поддерживается Spring Shell, который присваивает значения аргументам по порядку.

Примеры и объяснения ошибок

  1. Неименованный аргумент с неправильным флагом:
java .. experiment --async ABC

Здесь вы получаете ошибку, потому что передали ABC вместо просто указания --async. Параметр async имеет arity=OptionArity.ZERO, что означает, что он не ожидает какого-либо значения. Вы передали лишний аргумент ABC, что привело к ошибке конвертации типов.

  1. Правильное использование имени с флагом:
java .. experiment --async --path ABC

Здесь --async принимается как флаг (true), а --path — как обязательный параметр, и вызов выполняется без ошибок. Spring Shell справляется с заданием, поскольку параметр async не требует значений, а path получает значение ABC.

Заключение

Различие между именованными и неименованными аргументами в Spring Shell предоставляет возможность гибко конфигурировать команды. Важно помнить о порядке аргументов и значениях, ожидаемых определенными параметрами. Ваш пример показывает базовые принципы работы с командной оболочкой Spring, что значительно упрощает разработку командных интерфейсов в приложениях на базе Spring Boot. С обращением внимания на правильную структуру и логику передачи аргументов можно избежать распространенных ошибок и сделать интерфейс более удобным и интуитивным для пользователей.

Если у вас остались вопросы или требуется дополнительная поддержка, не стесняйтесь обращаться за разъяснениями!

Оцените материал
Добавить комментарий

Капча загружается...