简体   繁体   中英

Spring HandlerInterceptor called twice

In a library project (using Spring 3.2.4) I define multiple interceptors. The servlet config xml files are included in the jar to be imported in the web application. The interceptors are used in multiple servlet xmls, because they shall be used for different Dispatcher servlets with different interceptors.

The problem is, that the Interceptors are called twice, but the handler(controller) is just called once.

The interceptor is defined in the library project:

public class SomeInterceptor extends HandlerInterceptorAdapter {

        @Override
        public void afterCompletion(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception ex) throws Exception {
            System.out.println("afterCompletionCalled");
        }

        @Override
        public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) throws Exception {
            System.out.println("preHandle called");
            return true;
        }

        @Override
        public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final ModelAndView modelAndView) throws Exception {
        }
    }

The servlet configuration is provided in a jar file and later on included in the application.

libservletcfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

    <context:component-scan base-package="com.example.controller" annotation-config="true" />

    <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>

    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jacksonMessageConverter"/>
            </list>
        </property>
    </bean>

    <mvc:annotation-driven />

   <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.example.SomeInterceptor"/>
        </mvc:interceptor>    
    </mvc:interceptors>

</beans>

In the web application I just include the libservletcfg.xml in the servlet config.

servletConfig.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <import resource="classpath*:libservletcfg.xml"/>

    <context:component-scan base-package="com.example.app.controller" annotation-config="true" />

</beans>

This servletConfig.xml is used as context config for the Dispatcher servlet in the web.xml:

<servlet>
    <servlet-name>someServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:servletConfig.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>someServlet</servlet-name>
    <url-pattern>/someUrl/*</url-pattern>
</servlet-mapping>

Can anyone tell my why the interceptor is called twice or any problems with the configuration (which might lead to an unexpected behaviour)?

edit

Example of a Controller called twice:

@Controller
@RequestMapping(value = "/someUrl")
public class SampleController {

    @RequestMapping(method = RequestMethod.POST)
    public @ResponseBody SampleResponseBody sampleMethod(@RequestBody final SampleRequestBody pSampleRequestBody) {
        final SampleResponseBody response = new SampleResponseBody();
        return response;
    }

}

Check you don't have another libservletcfg.xml hanging around. classpath*: will match all of them.

我们面临着拦截器被调用两次的相同问题,这是因为我们在 web.xml 以及 @Configuration java 文件中定义了 applicationContext.xml。

I was also facing same issue, the interceptor was getting called twice. The issue was in @ComponentScan declaration of root config class, two instances were getting created, one in a web context and another in the root context.

So, after removing the interceptor package from the root context issue got fixed.

You need to use org.springframework.web.servlet.AsyncHandlerInterceptor :

public interface AsyncHandlerInterceptor extends HandlerInterceptor {

    void afterConcurrentHandlingStarted(
            HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception;

}

Spring MVCexecute sequence:

preHandle
afterConcurrentHandlingStarted
preHandle
postHandle
afterCompletion

Found from link and verified myself

Hope this helps !!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM