Spring MVC - Interceptor never called
Asked Answered
S

7

14

I am trying to configure an interceptor in my application and I am not being able to make it work.

In my application configuration class, I have configured in the following way:

@Configuration
@EnableWebMvc
public class AppContextConfiguration extends WebMvcConfigurerAdapter {
    ...
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor());
    }
    ...
}

And the interceptor:

public class MyInterceptor extends HandlerInterceptorAdapter{

    private static final Logger logger = LoggerFactory.getLogger(MyInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
        Object handler) throws Exception {

        logger.debug("MyInterceptor - PREHANDLE");
    }
}

Does anybody know why is not being invoked?

Slayton answered 25/3, 2014 at 11:53 Comment(8)
Put a log statement in addInterceptors. Is it logged?Justitia
Also, your intercept won't currently compile. Show us what you actually have.Justitia
Yes, if I put a log statement in addInterceptors it is logged, but the log statement in the preHandle method is never logged.Slayton
You don't seem to have registered a path for the interceptor.Justitia
I tried with: registry.addInterceptor(securityHandlerInterceptor()).addPathPatterns("/* *"); , registry.addInterceptor(securityHandlerInterceptor()).addPathPatterns("/account"); and registry.addInterceptor(securityHandlerInterceptor()); and it did not workedSlayton
Ok, what URL are you sending your requests to?Justitia
To localhost:8080/myapp/accountSlayton
How did you managed to solve it? i have the same problem now?Alleenallegation
B
41

I'm using Spring Boot and was having the same problem where addInterceptors() was being called to register the interceptor, but the interceptor never fired during a request. Yet XML configuration worked no problem.

Basically, you don't need the WebMvcConfigurerAdapter class. You just need to declare an @Bean of type MappedInterceptor:

@Bean
public MappedInterceptor myInterceptor()
{
    return new MappedInterceptor(null, new MyInterceptor());
}
Boutis answered 11/3, 2016 at 19:50 Comment(5)
I am not sure what the underlying problem is, but this solved my problem. Thank you!Canoness
@Boutis do you have any idea why it's not working with registry.addInterceptor()?Blankbook
After a HUGE amount of researches, this is absolutely the only one RIGHT solution in order to configure an http interceptor on a old Spring MVC Framework (3 and 4).Precisian
@theo It worked bro!! Thanks for existing :)Seeing
thank you very much! After hours of messing around, this solution immediately helped.Bobette
S
5

Interceptor classes must be declared in spring context xml configuration file within the tag <mvc:interceptors>. Did you do that?

From the Documentation

An example of registering an interceptor applied to all URL paths:

<mvc:interceptors>
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>

An example of registering an interceptor limited to a specific URL path:

<mvc:interceptors>
    <mvc:interceptor>
        <mapping path="/secure/*"/>
        <bean class="org.example.SecurityInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

So, you would need to configure MyInterceptor class in the spring context xml file

Scary answered 25/3, 2014 at 12:5 Comment(5)
You can configure it as you said, via XML. But you can also configure via Java, and this is the way I am working in my application, trying to avoid the XML if is possible. However, the Java configuration should be as simple as the code I posted, but it does not work...Slayton
Yes, I agree. What is the version of Spring you use? How did you confirm that it is not invoked?Scary
I am using Spring 3.1.2, and I know that it is not being invoked because the log message is not being printed.Slayton
ok, do you have component scan configured somewhere? @ComponentScan(basePackages="webapp.base.package")Scary
Yes, I have. In fact, i had no problems with other beans which I have also configured via annotations, so this is mainly why I don't understand why it is not recognising the interceptorSlayton
R
4

Can someone please mark Theos answer as the correct one? I had the situation of a perfectly working Spring Boot app using i18n and Thymeleaf (with a layout interceptor) as long as the app was running localhost with the following config:

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(localeChangeInterceptor());
    registry.addInterceptor(thymeleafLayoutInterceptor());
}

As soon as I deployed the app to an Elasticbeanstalk instance, both interceptors were not fired anymore. Although added once. When I changed the setting to

@Bean
public MappedInterceptor localeInterceptor() {
    return new MappedInterceptor(null, localeChangeInterceptor());
}

@Bean
public MappedInterceptor thymeleafInterceptor() {
    return new MappedInterceptor(null, thymeleafLayoutInterceptor());
}

everything was working fine on all environments. There must be an issue with firing interceptors added with addInterceptor, it might depend on the URL that is used to invoke the request - I don't know.

Thanks for your answer, Theo, I just wanted to add this here if some else stumbles upon this nice feature.

Rudolphrudwik answered 12/10, 2018 at 14:27 Comment(0)
H
0

Maybe you should add componentscan annotation in the file where the main class is present.

@ComponentScan("package where the interceptor is placed.")

Worked for me.

Hollis answered 10/12, 2019 at 9:11 Comment(0)
F
0

This approach worked with me


@Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter {
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new MyInterceptor());
  }
}

Fashoda answered 7/2, 2021 at 18:49 Comment(0)
T
0

Using XML configuration, ensure you defined the interceptors in the correct context. Moving config from servlet context(*-servlet) to main context (web.xml) made it work.

Even if the URL was a call to the servlet.

Tadeo answered 20/1, 2022 at 8:47 Comment(0)
A
-1

If it´s possible. Use this approach:

public class Application extends WebMvcConfigurerAdapter{
...
@Bean
public MyInterceptor myInterceptor() {
    return new MyInterceptor();
}

public @Override void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(myInterceptor());
}
}

instead of:

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

because with the first you can use injection features (like @Autowired, etc...)

Audacious answered 27/9, 2016 at 10:44 Comment(1)
Not relevant to the question.Exocrine

© 2022 - 2024 — McMap. All rights reserved.