I am creating an internal library that should automatically add multiple controllers to a Spring MVC application. These controllers are all @RestController with several handler methods annotated using @RequestMapping . Since this is a library, I want users to be able to specify the root path where the library should expose all of these controllers. Illustration:
// 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`
What I want to achieve is to make the /admin construct customizable. For example, if the user says in application.properties :
super.admin.path=/top/secret/location/here
I want the AdminController handlers AdminController be available at http://localhost/top/secret/location/here , so the allUsers() handler should have the full path:
http://localhost/top/secret/location/here/users
How do I achieve this? It feels like a pretty common task, but I was not able to find a direct solution that works.
My discovery # 1
There is a SimpleUrlHandlerMapping mechanism, which seems to be exactly what I want:
@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; }
But he keeps talking
HandlerAdapter that supports this handler must be enabled in the DispatcherServlet configuration
My discovery # 2
There Spring Boot Admin Project that has this exact function - you can configure where they should expose all their endpoints. It seems that this functionality is implemented from scratch in PrefixHandlerMapping . How do they use it:
... @Bean public PrefixHandlerMapping prefixHandlerMappingNotificationFilterController() { PrefixHandlerMapping prefixHandlerMapping = new PrefixHandlerMapping(notificationFilterController()); prefixHandlerMapping.setPrefix(adminServerProperties.getContextPath()); return prefixHandlerMapping; } ...