Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interceptor for not existing request mapping with java configuration

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.

like image 375
maszter Avatar asked Apr 08 '17 16:04

maszter


People also ask

How do you call an interceptor in Java?

Use the @AroundInvoke annotation to designate interceptor methods for managed object methods. Only one around-invoke interceptor method per class is allowed. Around-invoke interceptor methods have the following form: @AroundInvoke visibility Object method-name(InvocationContext) throws Exception { ... }

Which interceptor is used in an application when maintenance page needs to be shown?

Spring Interceptor are used to intercept client requests and process them.

How do you intercept all HTTP requests in spring boot?

To work with interceptor, you need to create @Component class that supports it and it should implement the HandlerInterceptor interface. preHandle() method − This is used to perform operations before sending the request to the controller. This method should return true to return the response to the client.


Video Answer


1 Answers

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.

like image 103
KeatsPeeks Avatar answered Oct 21 '22 12:10

KeatsPeeks