2

I am currently learning about spring and the concept of beans. I learned that in spring project you can configure in 3 ways -- xml, annotation-based and java-based. I am trying to configure my interceptor in all ways but the @Configuration way fails, the interceptor cannot be invoked this way. I don't know why the @Bean MappedInterceptor configuration invoke the interceptor, all I know is that there are probably some auto configuring behind the spring but I can't find any articles about it...

I've read this article, it says the mappedInterceptor bean won't work in plain spring but it helps me invoke the interceptor here. Although I think I am using plain spring now.

I've also read this article

InterceptorConfig:

@Configuration
@EnableWebMvc
public class InterceptorConfig implements WebMvcConfigurer {
    
    private final LoginAnnotationInterceptor loginAnnotationInterceptor;
    
    public InterceptorConfig(LoginAnnotationInterceptor loginAnnotationInterceptor) {
        this.loginAnnotationInterceptor = loginAnnotationInterceptor;
    }

    // the interceptor added here cannot be invoked
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginAnnotationInterceptor);
    }
    
    // the interceptor added here is able to be invoked
    @Bean
    public MappedInterceptor loginAnnotationInterceptorBean()
    {
        return new MappedInterceptor(null, loginAnnotationInterceptor);
    }
}

LoginAnnotationInterceptor:

@Component
public class LoginAnnotationInterceptor implements HandlerInterceptor  {
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
            throws Exception {
        System.out.println("It's an interceptor!");

        // some logic...

        return true;
    }
}

this is my lib...don't know if anything is wrong here

This is my web.xml. The context:component-scan/ part to scan the InterceptorConfig is defined in applicationContext.xml. I believe my configuration is loaded in DispatcherServlet.

web.xml:

<!-- Root Context -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/root-context.xml</param-value>
</context-param>
    
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- DispatcherServlet -->
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

applicationContext.xml:

<context:component-scan base-package="org.com.interceptor"/>

I tried to print out the beans in the ApplicationContext but still doesn't help, is there any other way to debug this problem or understand the reason behind it?

7
  • 2
    Have you connected the power? Sorry but stating "It doesn't work" isn't really helpful (as helpful as my first sentence). What doesn't work? Isn't it being invoked? Commented Jun 16 at 8:41
  • sorry for my poor explanation. The interceptor added by registry.addInterceptor() is not being invoked, and the one added by @Bean MappedInterceptor is able to be invoked Commented Jun 16 at 8:53
  • 1
    And it should be invoked because? The MappedInterceptor will probably execute and if the preHandle returns false it will not invoke the next interceptors. Next to that how and where is this configuration being loaded. If it is in the ROOT context (the ContextLoaderListener the @EnableWebMVc is pretty much useless and your addInterceptor will ultimatly be ignored. Where as the MappedInterceptor will still be detected as it detects MappedInterrceptors in the parent. The InterceptorConfig should be loaded by the DispatcherServlet and not the ContextLoaderListener Commented Jun 16 at 8:58
  • 1
    What is scanned and detected by what is impossible to know. We have no idea what is in your XML files, nor do we know the packages the classes reside in. Next to that I would suggest to rename the root-context.xml to applicationContext.xml (default loaded by ContextLoaderListener) and applicationContext.xml to dispatcher-servlet.xml (which will then be automatically loaded by the DispatcherServlet. Another thing is why XML why not simply java based config and a WebApplicationInitializer to bootstrap your app ... Commented Jun 16 at 9:39
  • 1
    There isn't really a problem combining xml and java, in fact initially that was the only way to get things started. But as stated from the symptoms you mention it appears as if things are applied at th ContextLoaderListener level and not the DispatcherServlet level. Commented Jun 16 at 10:20

1 Answer 1

2

May be not a fix for your exact issue, but if all you need is to intercept your request/responses then you can perhaps use Filters. You don't need to add any filter config or anything jsut creating a component that extends the Filter class will do.

Taking your example class -

@Slf4j
@Component
public class LoginFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest request, 
                         ServletResponse response, 
                         FilterChain chain) throws IOException, ServletException {
        
        log.info("Here's your request - {}", request);
        // some logic with your request before your API gets processed...

        chain.doFilter(request, response); // request goes to service layer.

        log.info("Here's your original request - {}", request);
        log.info("Here's your response- {}", response);
        // some logic with your response before your API sends out the response...
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your response! I am learning Filter as well, but as I know the request won't reach the annotated RequestMapping method before it passes by the filter. My LoginAnnotationInterceptor is to check if the RequestMapping method also happens to have my custom annotation @Login, if so, my interceptor will check the session to make sure the request is sent with a login verification before it gets into the method. So filter isn't the way I choose to do so, although I know many people use filter to verify the login problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.