• 【Java Web开发学习】Spring MVC 拦截器HandlerInterceptor


    【Java Web开发学习】Spring MVC 拦截器HandlerInterceptor

    转载:https://www.cnblogs.com/yangchongxing/p/9324119.html

    目录

    1、拦截器接口代码
    2、拦截器方法调用顺序
    3、自定义拦截器实现
    4、拦截器配置

    正文

    1、拦截器接口代码

    /*
     * Copyright 2002-2016 the original author or authors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package org.springframework.web.servlet;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.method.HandlerMethod;
    
    /**
     * Workflow interface that allows for customized handler execution chains.
     * Applications can register any number of existing or custom interceptors
     * for certain groups of handlers, to add common preprocessing behavior
     * without needing to modify each handler implementation.
     *
     * <p>A HandlerInterceptor gets called before the appropriate HandlerAdapter
     * triggers the execution of the handler itself. This mechanism can be used
     * for a large field of preprocessing aspects, e.g. for authorization checks,
     * or common handler behavior like locale or theme changes. Its main purpose
     * is to allow for factoring out repetitive handler code.
     *
     * <p>In an asynchronous processing scenario, the handler may be executed in a
     * separate thread while the main thread exits without rendering or invoking the
     * {@code postHandle} and {@code afterCompletion} callbacks. When concurrent
     * handler execution completes, the request is dispatched back in order to
     * proceed with rendering the model and all methods of this contract are invoked
     * again. For further options and details see
     * {@code org.springframework.web.servlet.AsyncHandlerInterceptor}
     *
     * <p>Typically an interceptor chain is defined per HandlerMapping bean,
     * sharing its granularity. To be able to apply a certain interceptor chain
     * to a group of handlers, one needs to map the desired handlers via one
     * HandlerMapping bean. The interceptors themselves are defined as beans
     * in the application context, referenced by the mapping bean definition
     * via its "interceptors" property (in XML: a &lt;list&gt; of &lt;ref&gt;).
     *
     * <p>HandlerInterceptor is basically similar to a Servlet Filter, but in
     * contrast to the latter it just allows custom pre-processing with the option
     * of prohibiting the execution of the handler itself, and custom post-processing.
     * Filters are more powerful, for example they allow for exchanging the request
     * and response objects that are handed down the chain. Note that a filter
     * gets configured in web.xml, a HandlerInterceptor in the application context.
     *
     * <p>As a basic guideline, fine-grained handler-related preprocessing tasks are
     * candidates for HandlerInterceptor implementations, especially factored-out
     * common handler code and authorization checks. On the other hand, a Filter
     * is well-suited for request content and view content handling, like multipart
     * forms and GZIP compression. This typically shows when one needs to map the
     * filter to certain content types (e.g. images), or to all requests.
     *
     * @author Juergen Hoeller
     * @since 20.06.2003
     * @see HandlerExecutionChain#getInterceptors
     * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter
     * @see org.springframework.web.servlet.handler.AbstractHandlerMapping#setInterceptors
     * @see org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor
     * @see org.springframework.web.servlet.i18n.LocaleChangeInterceptor
     * @see org.springframework.web.servlet.theme.ThemeChangeInterceptor
     * @see javax.servlet.Filter
     */
    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;
    
    }

    2、拦截器方法调用顺序

    preHandle:在Controller方法调用之前执行,主要进行初始化操作。返回值:true表示继续流程,false表示流程中断。
    postHandle:在Controller方法调用之后渲染视图之前执行。
    afterCompletion:整个请求处理完毕,视图渲染完成后执行。

    3、自定义拦截器实现

    Spring提供了适配器HandlerInterceptorAdapter,我们只要实现适配器中需要的方法即可

    public class AuthenticationInterceptor extends HandlerInterceptorAdapter {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
            System.out.println(">>> preHandle");
            return true;
        }
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println(">>> postHandle");
        }
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println(">>> afterCompletion");
        }
    }

    4、拦截器配置

    基于ant的通配符拦截所有/**。

    基于code-base

    @Configuration
    @EnableWebMvc //启用spirng mvc java配置,相当于<mvc:annotation-driven/>
    @ComponentScan(
            basePackages = {"cn.ycx.web.controller"},
            // 仅仅扫描
            includeFilters = {@Filter( type=FilterType.ANNOTATION, value={org.springframework.stereotype.Controller.class} )}
            )
    public class ServletConfig extends WebMvcConfigurerAdapter {
        /**
         * 自定义拦截器
         * @return
         */
        @Bean
        public AuthenticationInterceptor handlerInterceptor() {
            return new AuthenticationInterceptor();
        }
        /**
         * 添加拦截器
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(handlerInterceptor())
                    .addPathPatterns("/**")
                    .excludePathPatterns(new String[] {
                            "/",
                            "/login",
                            "/resource/**"
                    });
        }
    }

    基于xml-base

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="cn.ycx.web.interceptor.AuthenticationInterceptor" ></bean>
        </mvc:interceptor>
    </mvc:interceptors>
  • 相关阅读:
    元数据的优势
    老婆从今天开始出差
    清单元数据表中的导出类型定义
    Singleton模式
    拖管代码的优势
    元数据
    "软件随想录"阅读笔记
    《敏捷软件开发》学习笔记:敏捷设计原则
    项目管理中的三个"凡是"
    Python基础(1):数据类型
  • 原文地址:https://www.cnblogs.com/yangchongxing/p/9324119.html
Copyright © 2020-2023  润新知