Почему GET запрос не попадает в метод с аннотацией @GetMapping с параметрами в Spring?

Имеется метод в контроллере, который обрабатывает GET запрос. Данный метод помечен аннотацией @GetMapping(params = {ParameterName.SORT_BY, ParameterName.SORT_TYPE}). У данного метода в аргументах с помощью аннотации @RequestParam идет привязка аргумента, пришедшего из GET запроса к переменной Java типа String. Выглядит это следующим образом:

@GetMapping(params = {ParameterName.SORT_BY, ParameterName.SORT_TYPE})
    public List<GiftCertificate> findAllAndSort(@RequestParam(value = ParameterName.SORT_BY) String sortBy,
                                                @RequestParam(value = ParameterName.SORT_TYPE, required = false) String sortType) {
        log.info("Sorting: {}, {}", sortBy, sortType);

        return service.findAllAndSort(sortType, sortBy);
    }

У аргумента sortType стоит required = false, что означает, что данный аргумент не обязательно должен присутствовать: @RequestParam(value = ParameterName.SORT_TYPE, required = false) String sortType).

В исходниках написано:

The parameters of the mapped request, narrowing the primary mapping. Same format for any environment: a sequence of "myParam=myValue" style expressions, with a request only mapped if each such parameter is found to have the given value. Expressions can be negated by using the "!=" operator, as in "myParam!=myValue". "myParam" style expressions are also supported, with such parameters having to be present in the request (allowed to have any value). Finally, "!myParam" style expressions indicate that the specified parameter is not supposed to be present in the request. Supported at the type level as well as at the method level! When used at the type level, all method-level mappings inherit this parameter restriction.

Что значит, что все параметны, указанные в @GetMapping(params = {...}) должны присутствовать в запросе. Тогда зачем делать флаг required в @RequestParam?

Тогда вопрос, почему при запросе вида:

  1. http://localhost:8080/gift-certificates?sort_by=name&sort_type=DESC
    запрос попадает в данный метод.
  2. http://localhost:8080/gift-certificates?sort_by=name
    не попадает в данный метод

UPDATE
@roman-konoval Если аннотации работат на разных этапах, почему тогда такой вариант не работает?

@GetMapping
    public List<GiftCertificate> findAllAndSort(@RequestParam(value = ParameterName.SORT_BY) String sortBy,
                                                @RequestParam(value = ParameterName.SORT_TYPE, required = false) String sortType) {
        log.info("Sorting: {}, {}", sortBy, sortType);
        
return service.findAllAndSort(sortType, sortBy);
    }
    ```

Ответы (1 шт):

Автор решения: Taylor

Опишу ход эксперимента, чтобы другим было полезнее.

Сначала я пробовал составить запрос вида:

http://localhost:8080/gift-certificates?sort_by=[name,description]

Но квадратные скобки [``] не поддерживаются, так как допустимые симолы GET запроса определены в стандарте RFC 7230 and RFC 3986.

В итоге пришёл к решения сделать два метода и заменил в аргументе String ... sortBy на Set<String> sortBy. Теперь GET запрос выглядит:

http://localhost:8080/gift-certificates?sort_by=name&sort_by=description
@GetMapping(params = {ParameterName.SORT_BY})
    public List<GiftCertificate> findAllAndSort(@RequestParam(value = ParameterName.SORT_BY) Set<String> sortBy) {
        log.info("Sorting 1: {}", sortBy);

        return service.findAllAndSort(sortType, sortBy);
    }

@GetMapping(params = {ParameterName.SORT_BY, ParameterName.SORT_TYPE})
    public List<GiftCertificate> findAllAndSortWithSortType(@RequestParam(value = ParameterName.SORT_BY) Set<String> sortBy,
                                                            @RequestParam(value = ParameterName.SORT_TYPE) String sortType) {
        log.info("Sorting 2: {}, {}", sortBy, sortType);

        return service.findAllAndSort(sortType, sortBy);
    }

Но вопрос организации данной ситуации с помощью одного метода остается открытым.

→ Ссылка