Comparison of Several Interceptors in spring mvc

  springboot

Order

This article mainly compares several types of interceptors that can be used in spring mvc.

Classification

Mainly divided into Filter and interceptor.

Filter

Is a Filter in servlet specification, spring has a basic implementation called org/spring framework/web/filter/genericfilterbean.java.

public abstract class GenericFilterBean implements
        Filter, BeanNameAware, EnvironmentAware, ServletContextAware, InitializingBean, DisposableBean {

    @Override
    public final void setBeanName(String beanName) {
        this.beanName = beanName;
    }
    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
    @Override
    public final void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }
    @Override
    public void afterPropertiesSet() throws ServletException {
        initFilterBean();
    }
}
//......

This class mainly implements several interfaces of spring’s life cycle, which is convenient to be incorporated into IOC container management as bean.
If it is defined in web.xml, it supports mapping parameters to attributes in bean.

OncePerRequestFilter

In spring, filters all inherit OncePerRequestFilter by default. He ensures that a request passes through filter only once and does not repeat execution.

This method is specially designed to be compatible with different web container (JSR168), that is, not all Containers are filtered once as we expect, and servlet versions are different. In order to be compatible with various running environments and versions, it is a relatively safe choice for the default filter to inherit OncePerRequestFilter.

public abstract class OncePerRequestFilter extends GenericFilterBean {

public static final String ALREADY_FILTERED_SUFFIX = ".FILTERED";

protected String getAlreadyFilteredAttributeName() {
        String name = getFilterName();
        if (name == null) {
            name = getClass().getName();
        }
        return name + ALREADY_FILTERED_SUFFIX;
    }
  //......
}

Identifies whether the filter has been executed by filtername+already _ filtered _ suffix.

HandlerInterceptor

org/springframework/spring-webmvc/4.3.9.RELEASE/spring-webmvc-4.3.9.RELEASE-sources.jar! /org/springframework/web/servlet/HandlerInterceptor.java

Execute based on execution chains

public interface HandlerInterceptor {

    /**
     * Intercept the execution of a handler. Called after HandlerMapping determined
     * an appropriate handler object, but before HandlerAdapter invokes the handler.
     * <p>DispatcherServlet processes a handler in an execution chain, consisting
     * of any number of interceptors, with the handler itself at the end.
     * With this method, each interceptor can decide to abort the execution chain,
     * typically sending a HTTP error or writing a custom response.
     * <p><strong>Note:</strong> special considerations apply for asynchronous
     * request processing. For more details see
     * {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
     * @param request current HTTP request
     * @param response current HTTP response
     * @param handler chosen handler to execute, for type and/or instance evaluation
     * @return {@code true} if the execution chain should proceed with the
     * next interceptor or the handler itself. Else, DispatcherServlet assumes
     * that this interceptor has already dealt with the response itself.
     * @throws Exception in case of errors
     */
    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception;

    /**
     * Intercept the execution of a handler. Called after HandlerAdapter actually
     * invoked the handler, but before the DispatcherServlet renders the view.
     * Can expose additional model objects to the view via the given ModelAndView.
     * <p>DispatcherServlet processes a handler in an execution chain, consisting
     * of any number of interceptors, with the handler itself at the end.
     * With this method, each interceptor can post-process an execution,
     * getting applied in inverse order of the execution chain.
     * <p><strong>Note:</strong> special considerations apply for asynchronous
     * request processing. For more details see
     * {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
     * @param request current HTTP request
     * @param response current HTTP response
     * @param handler handler (or {@link HandlerMethod}) that started asynchronous
     * execution, for type and/or instance examination
     * @param modelAndView the {@code ModelAndView} that the handler returned
     * (can also be {@code null})
     * @throws Exception in case of errors
     */
    void postHandle(
            HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception;

    /**
     * Callback after completion of request processing, that is, after rendering
     * the view. Will be called on any outcome of handler execution, thus allows
     * for proper resource cleanup.
     * <p>Note: Will only be called if this interceptor's {@code preHandle}
     * method has successfully completed and returned {@code true}!
     * <p>As with the {@code postHandle} method, the method will be invoked on each
     * interceptor in the chain in reverse order, so the first interceptor will be
     * the last to be invoked.
     * <p><strong>Note:</strong> special considerations apply for asynchronous
     * request processing. For more details see
     * {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
     * @param request current HTTP request
     * @param response current HTTP response
     * @param handler handler (or {@link HandlerMethod}) that started asynchronous
     * execution, for type and/or instance examination
     * @param ex exception thrown on handler execution, if any
     * @throws Exception in case of errors
     */
    void afterCompletion(
            HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception;

}

Three methods are mainly defined: preHandle, postHandle, afterCompletion

  • preHandle
    If false is returned in this, execution will stop.
  • postHandle
    The post-processing callback method implements the post-processing of the processor, but it can be executed before rendering the view, where additional variables can be added to the view (executed when the preHandle is successfully executed and returns true)
  • afterCompletion
    The callback method is executed when the preHandle is successfully executed and returns true. the callback method is executed when the entire request is processed, that is, when the view is rendered.

Contrast

Type Range Execute chain processing abnormal Classic and practical
filter Filter is a servlet definition that can be supported in servlet-supported containers. The doFilter method does not return a value. each filter is used to control whether to execute downwards. if you do not want to execute downwards, you can set the response body and status yourself and then return in advance. Exception cannot be caught by spring’s ExceptionHandler, directly 500 CharacterEncodingFilter
CorsFilter
CsrfFilter
MetricsFilter
MultipartFilter
OpenEntityManagerInViewFilter
WebRequestTraceFilter
HandlerInterceptor Supported in spring mvc The preHandle method returns a boolean value. when the boolean value is true, it will continue to execute the next interceptor, and when false, it will return immediately. you can set the response body and status yourself, or throw exceptions. spring will intercept and process them uniformly. Exceptions can be caught by ExceptionHandler. MvcEndpointSecurityInterceptor
UserRoleAuthorizationInterceptor

The number of filter used to record time-consuming and so on is more and more comprehensive. There are many HandlerInterceptor used to perform authentication, of course filter can be used.

doc