Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What could be causing RequestMappingHandlerMapping to not register correctly?

I'm trying to register a HandlerInterceptorAdapter instance though no matter what I do it doesn't get executed.

I've tried copying the example from the spring documentation with no luck.

Could it be that <annotation-driven> is doing something that could be preventing my interceptor from being registered?

I tried removing the id from handlerMapping though that only caused spring to register two instances in the container.

I've tried registering in both the root context and the servlet context.

Full servlet-context.xml

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

  <!-- Configures the @Controller programming model -->
  <annotation-driven/>

  <beans:bean id="handlerMapping"
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
    <beans:property name="interceptors">
      <beans:list>
        <beans:ref bean="officeHoursInterceptor"/>
      </beans:list>
    </beans:property>
  </beans:bean>
  <beans:bean id="officeHoursInterceptor"
        class="com.johnsands.web.servlet.TimeBasedAccessInterceptor">
    <beans:property name="openingTime" value="9"/>
    <beans:property name="closingTime" value="18"/>
  </beans:bean>

  <!-- ReST Exception Handling
       http://www.stormpath.com/blog/spring-mvc-rest-exception-handling-best-practices-part-1
       -->
  <beans:bean id="restExceptionResolver"
              class="com.stormpath.spring.web.servlet.handler.RestExceptionHandler">
    <beans:property name="order" value="100"/>
    <beans:property name="errorConverter">
      <beans:bean class="com.johnsands.spring.web.servlet.handler.BasicRestErrorConverter"/>
    </beans:property>
    <beans:property name="errorResolver">
      <beans:bean class="com.stormpath.spring.web.servlet.handler.DefaultRestErrorResolver">
        <beans:property name="localeResolver" ref="localeResolver"/>
        <beans:property name="defaultMoreInfoUrl" value="mailto:[email protected]"/>
        <beans:property name="exceptionMappingDefinitions">
          <beans:map>
            <!-- 404 -->
            <beans:entry key="com.johnsands.api.ResourceNotFoundException" value="404, _exmsg"/>

            <!-- 500 (catch all): -->
            <beans:entry key="Throwable" value="500"/>
          </beans:map>
        </beans:property>
      </beans:bean>
    </beans:property>
  </beans:bean>

  <beans:bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver"/>

  <!-- Handles HTTP GET requests for /static/** by efficiently serving up static resources in the ${webappRoot}/static/ directory -->
  <resources mapping="/static/**" location="/static/" />

  <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
  <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
  </beans:bean>

  <!-- Imports user-defined @Controller beans that process client requests -->
  <beans:import resource="controllers.xml" />

</beans:beans>

controllers.xml doesn't do much

<!-- Maps '/' requests to the 'home' view -->
<mvc:view-controller path="/" view-name="home"/>
<mvc:view-controller path="/login" view-name="login" />
<mvc:view-controller path="/logout" view-name="logout" />

<!-- Scans the classpath of this application for @Components to deploy as beans -->
<context:component-scan base-package="com.johnsands" />

Handler is as follows:

public class TimeBasedAccessInterceptor
        extends HandlerInterceptorAdapter {

    private static final Logger log =
            LoggerFactory.getLogger(TimeBasedAccessInterceptor.class);
    private int openingTime;
    private int closingTime;

    public TimeBasedAccessInterceptor() {
        log.info(" *** Constructing Instance *** ");
    }

    public void setOpeningTime(int openingTime) {
        this.openingTime = openingTime;
    }

    public void setClosingTime(int closingTime) {
        this.closingTime = closingTime;
    }

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {
        log.info(" *** (preHandle) *** ");
        Calendar cal = Calendar.getInstance();
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        if (openingTime <= hour && hour < closingTime) {
            return true;
        } else {
            response.sendRedirect("http://www.google.com.au");
            return false;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response,
                           Object handler,
                           ModelAndView modelAndView)
            throws Exception {
        log.info(" *** (postHandle) *** ");
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response,
                                Object handler,
                                Exception ex)
            throws Exception {
        log.info(" *** (afterCompletion) *** ");
    }

}
like image 424
Brett Ryan Avatar asked Aug 24 '12 17:08

Brett Ryan


1 Answers

Yes, you are right about <mvc:annotation-driven/> overriding the RequestMappingHandlerMapping that you have created with the custom interceptor registered through it. The way to register the interceptor is instead with a <mvc:interceptors..>:

<mvc:interceptors>
    <bean class=".."/>
</mvc:interceptors>

Or if you want it at a specific mapping:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/test"/>
        <bean class="test"></bean>
    </mvc:interceptor>
</mvc:interceptors>

If you want an explicit RequestMappingHandlerMapping, then you will also need to define the HandlerAdapter to go with it and remove mvc:annotation-driven

like image 69
Biju Kunjummen Avatar answered Oct 26 '22 22:10

Biju Kunjummen