Как мне настроить путь отображения @Controller?
Я строю внутреннюю библиотеку, которая должна автоматически добавить несколько контроллеров в приложение Spring MVC. Эти контроллеры все @RestController
с несколькими методами-обработчиками, аннотированными @RequestMapping
, Поскольку это библиотека, я хочу, чтобы пользователи могли указывать корневой путь, в котором библиотека должна предоставлять все эти контроллеры. Иллюстрация:
// given that I have a controller like this:
@RestController
@RequestMapping("/admin")
class AdminController {
@RequestMapping("/users")
UsersDto allUsers() { ... }
}
// it will be exposed at `http://localhost/admin/users`
Чего я хочу добиться, так это сделать /admin
часть настраивается. Например, если пользователь говорит в application.properties
:
super.admin.path=/top/secret/location/here
я хочу AdminController
обработчики будут доступны на http://localhost/top/secret/location/here
и так allUsers()
У обработчика должен быть полный путь:
http://localhost/top/secret/location/here/users
Как мне этого добиться? Похоже, довольно распространенная задача, но мне не удалось найти простое решение, которое работает.
Мое нахождение #1
Есть SimpleUrlHandlerMapping
механизм, который, кажется, именно то, что я хочу:
@Bean
public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping();
simpleUrlHandlerMapping.setOrder(Integer.MAX_VALUE - 2);
simpleUrlHandlerMapping.setUrlMap(Collections.singletonMap("/ANY_CUSTOM_VALUE_HERE/*", "adminController"));
return simpleUrlHandlerMapping;
}
Но это продолжает говорить
Конфигурация DispatcherServlet должна включать в себя HandlerAdapter, который поддерживает этот обработчик
Моя находка № 2
Есть проект Spring Boot Admin, который имеет именно эту функцию - вы можете настроить, где они должны выставлять все свои конечные точки. Похоже, они реализовали эту функциональность с нуля в PrefixHandlerMapping. Как они это используют:
...
@Bean
public PrefixHandlerMapping prefixHandlerMappingNotificationFilterController() {
PrefixHandlerMapping prefixHandlerMapping = new PrefixHandlerMapping(notificationFilterController());
prefixHandlerMapping.setPrefix(adminServerProperties.getContextPath());
return prefixHandlerMapping;
}
...
1 ответ
В дополнение к @M. Решение Deinum, вы можете использовать паттерны путей с заполнителями. В документации Spring говорится:
Шаблоны в
@RequestMapping
поддержка аннотаций${…}
заполнители для локальных свойств и / или системных свойств и переменных среды. Это может быть полезно в тех случаях, когда путь, на который отображается контроллер, может потребоваться настроить с помощью конфигурации.
Так что в вашем случае ваш контроллер будет выглядеть так:
@RestController
@RequestMapping("/${super.admin.path:admin}")
class AdminController {
// Same as before
}
Предыдущий контроллер будет использовать super.admin.path
локальное / системное свойство или значение переменной среды в качестве префикса или admin
если они не предоставлены. Если вы используете Spring Boot, добавив следующее application.properties
:
super.admin.path=whatever
Вы можете настроить этот префикс.