Недавно столкнулся с задачей реализовать контроллер, различным образом обрабатывающий ситуации, где есть параметры запроса и где их нет. Проблема усугублялась тем, что нужны были именно два разных метода в контроллере. Стандартные возможности Spring MVC не позволяли этого сделать. Пришлось копнуть чуть глубже. Кому интересно — добро пожаловать под кат. Вот небольшой тест, который описывает сущность задачи.  Однако Spring был не так дружелюбен, как ожидалось, и на выходе получил: Были предприняты попытки разделить маппинг этих методов через аннотацию @RequestMapping(params = "some condition"), но к сожалению в используемой версии Spring 5.1.8 нет возможность задать условие на то, чтобы запрос содержал какие-то параметры. Можно задать либо наличие параметров с конкретными именами, либо отсутствие параметров с конкретными именами. Ни то, ни другое не подходило, т.к. параметры могли быть в каждом запросе разными. Хотелось бы написать что-то в этом роде @RequestMapping(params = "*") для указания, что запрос должен содержать какие-то параметры или @RequestMapping(params = "!*")` — для указания, что в запросе не должно быть никаких параметров. Покурив документацию, был найден раздел CustomAnnotations, в котором видим: Было принято решение  сделать свою аннотацию, которая позволила указать нужные мне условия на наличие параметров запроса.
  Я хочу добавить к методу аннотацию @NoRequestParams, указав таким образом, что этот метод обрабатывает запросы без параметров. Контроллер с нашей аннотацией: Стандартная конфигурация Spring-MVC, активируемая аннотацией @EnableWebMvc описана в классе WebMvcConfigurationSupport. Она инстанцирует бин класса RequestMappingHandlerMapping, который реализует маппинг, используя для этого объекты класса RequestMappingInfo, которые в свою очередь инкапсулируют в себе информацию о маппинге запросов на методы. Эта информация представлена в виде условий — объектов классов, реализующих интерфейс RequestCondition. В Spring имеются 6 готовых реализаций:


 В дополнение к этим реализациям мы можем определить свою. Для этого нам нужно реализовать интерфейс RequestCondition, и использовать эту реализацию для своих нужд. Можно реализовать интерфейс напрямую или же воспользоваться абстрактным классом
AbstractRequestCondition. Первые два метода используются для строкового представления нашего условия. Метод T combine(T other) нужен для комбинирования условий, например, при наличии аннотации на методе и классе. В таком случае для комбинирования используется метод combine. Наша аннотация не предполагает комбинирования — поэтому мы просто возвращаем наш текущий экземпляр условия. Метод int compareTo(T other, HttpServletRequest request) служит для сравнения условий в контексте некоего запроса. Т.е. при наличии нескольких однотипных условий для запроса, выясняет какое из них наиболее специфично. Но опять же наше условие единственно возможное поэтому мы просто возвращаем 0, т.е. все наши условия равны между собой. Основная логика работы содержится в методе T getMatchingCondition(HttpServletRequest request). В этом методе мы должны решить для запроса, применяется ли к нему наше условие или нет. Если да, то возвращаем объект условия. Если нет — возвращаем null. В нашем случае мы возвращаем объект условия, если запрос не содержит в себе никаких параметров. Теперь нам нужно подключить наше условие в процесс маппинга. Чтобы это сделать мы унаследуемся от стандартной реализации RequestMappingHandlerMapping
и переопределим метод getCustomMethodCondition(Method method), который как раз и создан для того, чтобы добавлять свои кастомизированые условия. Причем этот метод используется при определении условий для методов контроллера. Есть еще метод getCustomTypeCondition(Class<?> handlerType), который можно использовать для определения условий на основе информации о классе контроллера. В нашем случае он нам не нужен. В итоге имеем следующую реализацию: Логика не сложная — проверяем наличие нашей аннотации и, если она присутствует, возвращаем объект нашего условия. Чтобы подключить нашу реализацию маппинга, расширим стандартую Spring MVC конфигурацию: Добавляем нашу аннотацию в контроллер: и проверяем результат: Таким образом мы можем изменять логику маппинга в соответсвие с нашими нуждами и придумывать свои условия. Например, условия на IP адрес или же на используемый User-agent. Возможно, есть и более простые решения, но в любом случае собирать свой велосипед тоже иногда полезно. Спасибо за внимание. Код примера на гитхабе