9

I have a configuration class, which extends WebMvcConfigurationSupport and I have added interceptors like this:

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(myInterceptor()).addPathPatterns("/api/**");
}

where myInterceptor() is:

@Bean
public MyInterceptor myInterceptor() {
    return new MyInterceptor();
}

and it works fine for any mapping (/api/**) which I have implemented for example /api/sample - preHandle from MyInterceptor is fired (I have a Controller with mapping /api/sample).

When I call not existing resource for example /api/forward/sample preHandle from MyInterceptor is never called.

Please notice it worked as expected when I had the config in xml, like:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/api/**" />
        <bean class="my.pack.MyInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

For some reason with java configuration requests for not existing mappings are not intercepted. Why the configuration is not equivalent? I thought it should be.

EDIT:

A bit more debugging information. With xml configuration DispatcherServlet#handlerMappings contains 5 handlers:

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.socket.server.support.WebSocketHandlerMapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping

with Java configuration it contains 7 handlers:

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.socket.server.support.WebSocketHandlerMapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport$EmptyHandlerMapping
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport$EmptyHandlerMapping
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping

The problem seems to be with SimpleUrlHandlerMapping (at least it seems to be used for the resource I call - api/forward/sample while for api/sample RequestMappingHandlerMapping is in use) which has empty adoptedIterceptors in the case with Java based configuration.

EDIT 2:

Full source code for sample application (I tried to make it as small as possible just to demonstrate the effect): https://github.com/szprutamich/spring-demo

In class ConfigurationBase - configuration can be switched from xml based to java based with static field CONFIG.

With xml based config both urls work:

/api/sample
/api/forward/sample

With java based config forward does not work.

maszter
  • 3,680
  • 6
  • 37
  • 53

1 Answers1

3

Your question is about a "not existing request mapping", but in your XML configuration, it exists :

<default-servlet-handler xmlns="http://www.springframework.org/schema/mvc" /> This declares a default handler for all requests, and a request interceptor ony works if a valid handler is found. Remove this line and you will get the same behavior in both XML and Java configs : no default handler will be found and the interceptor won't work.

So for the interceptor to work on all requests in your Java configuration, you have to declare a default handler. You could override configureDefaultServletHandling but afaik it's not possible to configure interceptors on it. You may have to explicitly map /** in a default handling controller.

KeatsPeeks
  • 19,126
  • 5
  • 52
  • 83
  • I have: @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } which should does it. – maszter Apr 24 '17 at 12:38
  • http://stackoverflow.com/questions/5062586/equivalent-of-mvcdefault-servlet-handler-in-spring-annotation-based-configurati – maszter Apr 24 '17 at 12:42
  • 2
    Problem is, this does not automatically add interceptors to it, unlike the XML counterpart. You could provide your own default handler then use getMapping().addInterceptor on it but it's overkill imho, just map /** and it will work. – KeatsPeeks Apr 24 '17 at 12:43
  • 1
    @mazter from the doc of addInterceptors : `Override this method to add Spring MVC interceptors for pre- and post-processing of controller invocation.` => "of controller invocation", not of all requests – KeatsPeeks Apr 24 '17 at 12:45