15.4 Handler mappings

In previous versions of Spring, users were required to define HandlerMappings in the web application context to map incoming web requests to appropriate handlers. With the introduction of Spring 2.5, the DispatcherServlet enables the DefaultAnnotationHandlerMapping, which looks for @RequestMapping annotations on @Controllers. Typically, you do not need to override this default mapping, except when overriding the properties. These properties are:

[Note]Note

The alwaysUseFullPath,urlDecode, and lazyInitHandlers properties are only available to subclasses of org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.

The following example shows how to override the default mapping and add an interceptor:

<beans>
  <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
      <bean class="example.MyInterceptor"/>
    </property>
  </bean>

<beans>

15.4.1 Intercepting requests - the HandlerInterceptor interface

Spring's handler mapping mechanism includes handler interceptors, which are useful when you want to apply specific functionality to certain requests, for example, checking for a principal.

Interceptors located in the handler mapping must implement HandlerInterceptor from the org.springframework.web.servlet package. This interface defines three methods: one is called before the actual handler is executed; one is called after the handler is executed; and one is called after the complete request has finished. These three methods should provide enough flexibility to do all kinds of preprocessing and postprocessing.

The preHandle(..) method returns a boolean value. You can use this method to break or continue the processing of the execution chain. When this method returns true, the handler execution chain will continue, when it returns false, the DispatcherServlet assumes the interceptor itself has taken care of requests (and, for example, rendered an appropriate view) and does not continue executing the other interceptors and the actual handler in the execution chain.

The following example provides an interceptor that intercepts all requests and reroutes the user to a specific page if the time is not between 9 a.m. and 6 p.m.

<beans>
    <bean id="handlerMapping"
          class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="interceptors">
            <list>
                <ref bean="officeHoursInterceptor"/>
            </list>
        </property>
        <property name="mappings">
            <value>
                /*.form=editAccountFormController
                /*.view=editAccountFormController
            </value>
        </property>
    </bean>

    <bean id="officeHoursInterceptor"
          class="samples.TimeBasedAccessInterceptor">
        <property name="openingTime" value="9"/>
        <property name="closingTime" value="18"/>
    </bean>
<beans>
package samples;

public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {

    private int openingTime;
    private int closingTime;

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

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

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

        Calendar cal = Calendar.getInstance();
        int hour = cal.get(HOUR_OF_DAY);
        if (openingTime <= hour < closingTime) {
            return true;
        } else {
            response.sendRedirect("http://host.com/outsideOfficeHours.html");
            return false;
        }
    }
}

Any request coming in is intercepted by the TimeBasedAccessInterceptor. If the current time is outside office hours, the user is redirected to a static HTML file that says, for example, you can only access the website during office hours.

As you can see, the Spring adapter class HandlerInterceptorAdapter makes it easier to extend the HandlerInterceptor interface.