2

For my Spring Boot application I have a mix of static content (html, js, css, etc) hosted in /static, combined with a REST webservice which listens to calls at /api/1.0. The /static is handled automatically by Spring Boot. For the api prefix, I have created a new servlet dispatcher that listens to the prefixed address:

@Configuration
public class DispatcherConfiguration {

    public static final String API_PREFIX = "/api/1.0/*";

    @Bean
    public DispatcherServlet apiDispatcherServlet() {
         DispatcherServlet dispatcher = new DispatcherServlet();
         return dispatcher;
    }

    /**
     * Setup route for the REST service located at @see API_PREFIX
     * @return Servlet dispatcher
     */
    @Bean
    public ServletRegistrationBean apiDispatcher() {
        DispatcherServlet dispatcher = apiDispatcherServlet();

        ServletRegistrationBean registration = new ServletRegistrationBean(dispatcher, API_PREFIX);
        registration.setName("api");
        registration.setOrder(1);
        return registration;
    }
}

At first sight this configuration solves the problem as now calls to the rest-api work with the set prefix and are forwarded to the correct controllers. At second sight, both servlets still handle both type of calls, so static content is now also available at the api prefix, and controllers are still accessible at the root url. This is not exactly the intention.

The spring documentation mentions some interesting configuration options in sections 15.12.4 and 15.12.5, however, the application of this in combination with Spring Boot and non-xml configuration is not clear.

Also I found a post by Daniel which explains in great detail a similar concern, but it's a much more complex setup than what I have, and I don't see an an easy way to apply his solution to my use case.

I've tried and tested various solutions, but with little documentation on this, and with all the dynamic Bean loading it's hard to test and figure out why something does or doesn't work. I'm a few days into this now and definately stuck.

How can I seperate the handling of static content vs controllers by the servlets using java configuration? All configuration in my application is done in java, so I'm looking (preferably) for a no-xml solution.

Stern
  • 130
  • 1
  • 8

2 Answers2

1

I dont think you need that configuration. You can just annotate your controller classes. For example:

@RestController
@RequestMapping(value = "/api/1.0")
public class MyRestController
.... 
    @RequestMapping(method = RequestMethod.POST)
    public @ResponseBody Foo getFoo(RequestEntity<Bar> request) {
robjwilkins
  • 5,462
  • 5
  • 43
  • 59
  • Yes, I have considered this, but the downside is that I would need to hardcode the api prefix in every controller. I already have a few dozen controllers, and rather have this configuration centralised for future maintainability and extendability. – Stern Jul 15 '15 at 10:53
  • In retrospect this answer was much better than I initially thought; I was completely looking in the wrong direction. I have created an abstract superclass for controllers, which a) defines the base request mapping and b) allows me to do sanity checks on which api version a controller is build for. Thanks for the insight! I've voted up your answer. – Stern Jul 15 '15 at 12:01
0
  • Don't use a second DispatcherServlet
  • Create a constant with "/api/1.0" somewhere, let's say Constants.API_BASE_URL
  • Annotate every @Controller with @RequestMapping(value = Constants.API_BASE_URL)

This way you will have a central point where the base URL is configured and every annotated controller will have a URL mapping relative to it.

hzpz
  • 7,536
  • 1
  • 38
  • 44