精华内容
参与话题
问答
  • 详述 Spring MVC 框架中拦截器 Interceptor 的使用方法

    万次阅读 多人点赞 2017-03-30 17:02:05
    之前,也在网络上搜了很多关于Interceptor的文章,但感觉内容都大同小异,而且知识点零零散散,不太方便阅读。因此,正好借此机会,整理一篇关于拦截器的文章,在此分享给大家,以供大家参考阅读。2 拦截器2.1 概念...

    1 前言

    网络上关于Interceptor的文章,但感觉内容都大同小异,而且知识点零零散散,不太方便阅读。

    因此,整理一篇关于拦截器的文章,在此分享给大家,以供大家参考阅读。

    2 拦截器

    2.1 概念

    Java 里的拦截器是动态拦截action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用部分的方式。在 AOP(Aspect-Oriented Programming,面向切面编程)中拦截器用于在某个方法(包括构造器)或字段被访问之前进行拦截,然后在之前或之后加入某些操作。特别地,现阶段 Spring 自身仅支持基于方法的拦截操作!如果基于方法的拦截操作不能满足需求,可以使用 AspectJ 与 Spring 进行集成,以实现更细粒度或更多方面的拦截操作。

    2.2 原理

    拦截器Interceptor的拦截功能是基于 Java 的动态代理来实现的,具体可以参考博文「用 Java 实现拦截器 Interceptor 的拦截功能 」,也可以通过阅读 Spring 源代码来了解更为权威的实现细节。

    3 实现方法

    在 Spring 框架之中,我们要想实现拦截器的功能,主要通过两种途径,第一种是实现HandlerInterceptor接口,第二种是实现WebRequestInterceptor接口。接下来,我们分别详细的介绍两者的实现方法。

    3.1 HandlerInterceptor 接口

    HandlerInterceptor接口中,定义了 3 个方法,分别为preHandle()postHandle()afterCompletion(),我们就是通过复写这 3 个方法来对用户的请求进行拦截处理的。因此,我们可以通过直接实现HandlerInterceptor接口来实现拦截器的功能。不过在 Spring 框架之中,其还提供了另外一个接口和一个抽象类,实现了对HandlerInterceptor接口的功能扩展,分别为:AsyncHandlerInterceptorHandlerInterceptorAdapter.

    对于AsyncHandlerInterceptor接口,其在继承HandlerInterceptor接口的同时,又声明了一个新的方法afterConcurrentHandlingStarted();而HandlerInterceptorAdapter抽象类,则是更进一步,在其继承AsyncHandlerInterceptor接口的同时,又复写了preHandle方法。因此,AsyncHandlerInterceptor更像是一个过渡的接口。

    在实际应用中,我们一般都是通过实现HandlerInterceptor接口或者继承HandlerInterceptorAdapter抽象类,复写preHandle()postHandle()afterCompletion()这 3 个方法来对用户的请求进行拦截处理的。下面,我们就详细介绍这个 3 个方法。

    • preHandle(HttpServletRequest request, HttpServletResponse response, Object handle)方法,该方法在请求处理之前进行调用。Spring MVC 中的Interceptor是链式调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor。每个Interceptor的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor中的preHandle方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求做一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔(Boolean)类型的,当它返回为false时,表示请求结束,后续的Interceptor和控制器(Controller)都不会再执行;当返回值为true时,就会继续调用下一个InterceptorpreHandle方法,如果已经是最后一个Interceptor的时候,就会是调用当前请求的控制器中的方法。
    • postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)方法,通过preHandle方法的解释,我们知道这个方法包括后面要说到的afterCompletion方法都只能在当前所属的InterceptorpreHandle方法的返回值为true的时候,才能被调用。postHandle方法在当前请求进行处理之后,也就是在控制器中的方法调用之后执行,但是它会在DispatcherServlet进行视图返回渲染之前被调用,所以我们可以在这个方法中对控制器处理之后的ModelAndView对象进行操作。postHandle方法被调用的方向跟preHandle是相反的,也就是说,先声明的InterceptorpostHandle方法反而会后执行。这和 Struts2 里面的Interceptor的执行过程有点类似,Struts2 里面的Interceptor的执行过程也是链式的,只是在 Struts2 里面需要手动调用ActionInvocationinvoke方法来触发对下一个Interceptor或者是action的调用,然后每一个Interceptor中在invoke方法调用之前的内容都是按照声明顺序执行的,而invoke方法之后的内容就是反向的。
    • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法,也是需要当前对应的InterceptorpreHandle方法的返回值为true时才会执行。因此,该方法将在整个请求结束之后,也就是在DispatcherServlet渲染了对应的视图之后执行,这个方法的主要作用是用于进行资源清理的工作。

    接下来,我们在看看以上接口和抽象类的具体代码:

    HandlerInterceptor 接口:

    package org.springframework.web.servlet;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public interface HandlerInterceptor {
    
    	boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    	    throws Exception;
    
    	void postHandle(
    			HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
    			throws Exception;
    
    	void afterCompletion(
    			HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    			throws Exception;
    }
    

    AsyncHandlerInterceptor 接口:

    package org.springframework.web.servlet;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public interface AsyncHandlerInterceptor extends HandlerInterceptor {
    
    	void afterConcurrentHandlingStarted(
    			HttpServletRequest request, HttpServletResponse response, Object handler)
    			throws Exception;
    }
    

    HandlerInterceptorAdapter 抽象类:

    package org.springframework.web.servlet.handler;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.AsyncHandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    /**
     * Abstract adapter class for the HandlerInterceptor interface,
     * for simplified implementation of pre-only/post-only interceptors.
     *
     * @author Juergen Hoeller
     * @since 05.12.2003
     */
    public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
    
    	/**
    	 * This implementation always returns {@code true}.
    	 */
    	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    		throws Exception {
    		return true;
    	}
    
    	/**
    	 * This implementation is empty.
    	 */
    	public void postHandle(
    			HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
    			throws Exception {
    	}
    
    	/**
    	 * This implementation is empty.
    	 */
    	public void afterCompletion(
    			HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    			throws Exception {
    	}
    
    	/**
    	 * This implementation is empty.
    	 */
    	public void afterConcurrentHandlingStarted(
    			HttpServletRequest request, HttpServletResponse response, Object handler)
    			throws Exception {
    	}
    }
    

    如上面的代码所示,其实在HandlerInterceptorAsyncHandlerInterceptor中还有很多的代码注释,只是博主感觉太多了,就将其全部删除了。如果大家对这些注释感兴趣的话,可以自行查看源代码。下面,我们以继承HandlerInterceptorAdapter抽象类为例进行演示:

    package com.hit.interceptor;
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @author 维C果糖
     * @create 2017-03-31
     */
    public class WrongCodeInterceptor extends HandlerInterceptorAdapter {
        
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            System.out.println("WrongCodeInterceptor, preHandle......");
            return true;
        }
    
        @Override
        public void postHandle(
                HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
                throws Exception {
            System.out.println("WrongCodeInterceptor, postHandle......");
        }
    
        @Override
        public void afterCompletion(
                HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("WrongCodeInterceptor, afterCompletion......");
        }
    
        @Override
        public void afterConcurrentHandlingStarted(
                HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            System.out.println("WrongCodeInterceptor, afterConcurrentHandlingStarted......");
        }
    }
    

    3.2 WebRequestInterceptor 接口

    WebRequestInterceptor接口中也定义了 3 个方法,同HandlerInterceptor接口完全相同,我们也是通过复写这 3 个方法来对用户的请求进行拦截处理的。而且这 3 个方法都传递了同一个参数WebRequest,那么这个WebRequest到底是什么呢?其实这个WebRequest是 Spring 中定义的一个接口,它里面的方法定义跟HttpServletRequest类似,在WebRequestInterceptor中对WebRequest进行的所有操作都将同步到HttpServletRequest中,然后在当前请求中依次传递。

    在 Spring 框架之中,还提供了一个和WebRequestInterceptor接口长的很像的抽象类,那就是:WebRequestInterceptorAdapter,其实现了AsyncHandlerInterceptor接口,并在内部调用了WebRequestInterceptor接口。

    接下来,我们主要讲一下WebRequestInterceptor接口的 3 个函数:

    • preHandle(WebRequest request)方法,该方法在请求处理之前进行调用,也就是说,其会在控制器中的方法调用之前被调用。这个方法跟HandlerInterceptor中的preHandle不同,主要区别在于该方法的返回值是void类型的,也就是没有返回值,因此我们主要用它来进行资源的准备工作,比如我们在使用 Hibernate 的时候,可以在这个方法中准备一个 Hibernate 的Session对象,然后利用WebRequestsetAttribute(name, value, scope)把它放到WebRequest的属性中。在这里,进一步说说setAttribute方法的第三个参数scope,该参数是一个Integer类型的。在WebRequest的父层接口RequestAttributes中对它定义了三个常量,分别为:
      • SCOPE_REQUEST,它的值是0,表示只有在request中可以访问。
      • SCOPE_SESSION,它的值是1,如果环境允许的话,它表示的是一个局部的隔离的session,否则就代表普通的session,并且在该session范围内可以访问。
      • SCOPE_GLOBAL_SESSION,它的值是2,如果环境允许的话,它表示的是一个全局共享的session,否则就代表普通的session,并且在该session范围内可以访问。
    • postHandle(WebRequest request, ModelMap model)方法,该方法在请求处理之后,也就是在控制器中的方法调用之后被调用,但是会在视图返回被渲染之前被调用,所以可以在这个方法里面通过改变数据模型ModelMap来改变数据的展示。该方法有两个参数,WebRequest对象是用于传递整个请求数据的,比如在preHandle中准备的数据都可以通过WebRequest来传递和访问;ModelMap就是控制器处理之后返回的Model对象,我们可以通过改变它的属性来改变返回的Model模型。
    • afterCompletion(WebRequest request, Exception ex)方法,该方法会在整个请求处理完成,也就是在视图返回并被渲染之后执行。因此可以在该方法中进行资源的释放操作。而WebRequest参数就可以把我们在preHandle中准备的资源传递到这里进行释放。Exception参数表示的是当前请求的异常对象,如果在控制器中抛出的异常已经被 Spring 的异常处理器给处理了的话,那么这个异常对象就是是null

    接下来,我们在看看以上接口和抽象类的具体代码:

    WebRequestInterceptor 接口:

    package org.springframework.web.context.request;
    
    import org.springframework.ui.ModelMap;
    
    public interface WebRequestInterceptor {
    
    	void preHandle(WebRequest request) throws Exception;
    
    	void postHandle(WebRequest request, ModelMap model) throws Exception;
    
    	void afterCompletion(WebRequest request, Exception ex) throws Exception;
    
    }
    

    WebRequestInterceptorAdapter 抽象类:

    package org.springframework.web.servlet.handler;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.util.Assert;
    import org.springframework.web.context.request.AsyncWebRequestInterceptor;
    import org.springframework.web.context.request.WebRequestInterceptor;
    import org.springframework.web.servlet.AsyncHandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    /**
     * Adapter that implements the Servlet HandlerInterceptor interface
     * and wraps an underlying WebRequestInterceptor.
     *
     * @author Juergen Hoeller
     * @since 2.0
     * @see org.springframework.web.context.request.WebRequestInterceptor
     * @see org.springframework.web.servlet.HandlerInterceptor
     */
    public class WebRequestHandlerInterceptorAdapter implements AsyncHandlerInterceptor {
    
    	private final WebRequestInterceptor requestInterceptor;
    
    	/**
    	 * Create a new WebRequestHandlerInterceptorAdapter for the given WebRequestInterceptor.
    	 * @param requestInterceptor the WebRequestInterceptor to wrap
    	 */
    	public WebRequestHandlerInterceptorAdapter(WebRequestInterceptor requestInterceptor) {
    		Assert.notNull(requestInterceptor, "WebRequestInterceptor must not be null");
    		this.requestInterceptor = requestInterceptor;
    	}
    
    
    	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    			throws Exception {
    
    		this.requestInterceptor.preHandle(new DispatcherServletWebRequest(request, response));
    		return true;
    	}
    
    	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
    			throws Exception {
    
    		this.requestInterceptor.postHandle(new DispatcherServletWebRequest(request, response),
    				(modelAndView != null && !modelAndView.wasCleared() ? modelAndView.getModelMap() : null));
    	}
    
    	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    			throws Exception {
    
    		this.requestInterceptor.afterCompletion(new DispatcherServletWebRequest(request, response), ex);
    	}
    
    	public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) {
    		if (this.requestInterceptor instanceof AsyncWebRequestInterceptor) {
    			AsyncWebRequestInterceptor asyncInterceptor = (AsyncWebRequestInterceptor) this.requestInterceptor;
    			DispatcherServletWebRequest webRequest = new DispatcherServletWebRequest(request, response);
    			asyncInterceptor.afterConcurrentHandlingStarted(webRequest);
    		}
    	}
    }
    

    如上面的代码所示,展示了WebRequestInterceptor接口和WebRequestInterceptorAdapter抽象类的源码。下面,我们以实现WebRequestInterceptor接口为例进行演示:

    package com.hit.interceptor;
    
    import org.springframework.ui.ModelMap;
    import org.springframework.web.context.request.WebRequest;
    import org.springframework.web.context.request.WebRequestInterceptor;
    
    /**
     * @author 维C果糖
     * @create 2017-03-31
     */
    public class WrongCodeInterceptor implements WebRequestInterceptor {
    
        @Override
        public void preHandle(WebRequest request) throws Exception {
            System.out.println("WrongCodeInterceptor, preHandle......");
        }
    
        @Override
        public void postHandle(WebRequest request, ModelMap model) throws Exception {
            System.out.println("WrongCodeInterceptor, postHandle......");
        }
    
        @Override
        public void afterCompletion(WebRequest request, Exception ex) throws Exception {
            System.out.println("WrongCodeInterceptor, afterCompletion......");
        }
    }
    

    3.3 AbstractInterceptor 抽象类

    除了上面3.23.3所讲的内容,我们还可以通过继承 Struts2 框架提供的AbstractInterceptor抽象类来实现拦截的功能。如果我们在深入一点研究,会发现AbstractInterceptor实现了Interceptor接口,而Interceptor接口又继承了Serializable接口。

    Interceptor接口中,提供了 3 个方法供我们使用,分别为init()destroy()intercept(),由于AbstractInterceptor实现了Interceptor接口,因此我们就可以直接继承AbstractInterceptor,然后复写方法就可以啦!至于为什么继承AbstractInterceptor而不是直接实现Interceptor接口,是因为AbstractInterceptor已经帮我们实现了空的init()destroy()方法,不需要我们自己去复写了,我们直接复写intercept()方法就可以了。现在,我们大致了解一下这 3 个方法的作用:

    • init()方法,一般用来进行初始化操作;
    • destroy()方法,一般用来进行释放资源的操作;
    • intercept()方法,该方法是实现拦截功能的主要方法,我们就在该方法中编写拦截的逻辑。

    接下来,我们再看看以上接口和抽象类的具体代码:

    Interceptor 接口:

    package com.opensymphony.xwork2.interceptor;
    
    import com.opensymphony.xwork2.ActionInvocation;
    
    import java.io.Serializable;
    
    public interface Interceptor extends Serializable {
    
        /**
         * Called to let an interceptor clean up any resources it has allocated.
         */
        void destroy();
    
        /**
         * Called after an interceptor is created, but before any requests are processed using
         * {@link #intercept(com.opensymphony.xwork2.ActionInvocation) intercept} , giving
         * the Interceptor a chance to initialize any needed resources.
         */
        void init();
    
        /**
         * Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the
         * request by the {@link ActionInvocation} or to short-circuit the processing and just return a String return code.
         *
         * @param invocation the action invocation
         * @return the return code, either returned from {@link ActionInvocation#invoke()}, or from the interceptor itself.
         * @throws Exception any system-level error, as defined in {@link com.opensymphony.xwork2.Action#execute()}.
         */
        String intercept(ActionInvocation invocation) throws Exception;
    
    }
    

    AbstractInterceptor 接口:

    package com.opensymphony.xwork2.interceptor;
    
    import com.opensymphony.xwork2.ActionInvocation;
    
    /**
     * Provides default implementations of optional lifecycle methods
     */
    public abstract class AbstractInterceptor implements Interceptor {
    
        /**
         * Does nothing
         */
        public void init() {
        }
        
        /**
         * Does nothing
         */
        public void destroy() {
        }
    
        /**
         * Override to handle interception
         */
        public abstract String intercept(ActionInvocation invocation) throws Exception;
    }
    

    如上面的代码所示,展示了Interceptor接口和AbstractInterceptor抽象类的源码。下面,我们以继承AbstractInterceptor抽象类为例进行演示:

    package com.hit.interceptor;
    
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
    import org.apache.struts2.ServletActionContext;
    
    
    /**
     * @author 维C果糖
     * @create 2017-03-31
     */
    public class WrongCodeInterceptor  extends AbstractInterceptor {
    
    	/**
         * 通过拦截功能,验证用户是否登录
         */
        public String intercept(ActionInvocation invocation) throws Exception {
    
            UserInfo info = (UserInfo) ServletActionContext.getRequest().getSession().getAttribute("user");
    
            if(info != null && !info.getName().equals("") && !info.getPwd().equals("")) {
                return invocation.invoke();
            }
            return "login";
        }
    }
    

    UserInfo 类文件:

    /**
     * @author 维C果糖
     * @create 2017-03-31
     */
    public class UserInfo {
        String name;
        String pwd;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPwd() {
            return pwd;
        }
    
        public void setPwd(String pwd) {
            this.pwd = pwd;
        }
    }
    

    4 配置拦截器

    在前面,我们用了很大篇幅的内容讲述了拦截器如何实现,因此,我相信大家对于如何实现拦截器已经没有问题啦!接下来,我们在看看,如何在 XML 文件中配置拦截器,以使我们的拦截器生效。

    在配置拦截器之前,有 4 个名称的概念需要大家先了解一下,分别为:Join PointPointcutAdviceAdvisor

    • Join Point,表示“连接点”,它是程序运行中的某个阶段点,比如方法的调用、异常的抛出等;
    • Advice,表示“通知”,它是某个连接点所采用的处理逻辑,也就是向连接点注入的代码;
    • Pointcut,表示“切入点”,它是“连接点”的集合,是程序中需要注入Advice的位置的集合,指明Advice要在什么样的条件下才能被触发;
    • Advisor,它是PointcutAdvice的配置器,包括PointcutAdvice,是将Advice注入程序中Pointcut位置的代码。

    接下来,给出 XML 配置文件的声明:

    <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.0.xsd  
         http://www.springframework.org/schema/context  
         http://www.springframework.org/schema/context/spring-context-3.0.xsd  
         http://www.springframework.org/schema/mvc  
         http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  
    

    在 XML 文件的头部声明完成之后,我们就可以在 Spring 的配置文件中使用mvc标签啦!而在mvc标签中有一个名为mvc:interceptors的标签,该标签就是用于声明 Spring 拦截器的。下面,给出一个配置示例:

    <mvc:interceptors>  
        <!-- 使用 bean 定义一个 Interceptor,直接定义在 mvc:interceptors 下面的 Interceptor 将拦截所有的请求 -->  
        <bean class="com.hit.interceptor.WrongCodeInterceptor"/>  
        <mvc:interceptor>  
            <mvc:mapping path="/demo/hello.do"/>  
            <!-- 定义在 mvc:interceptor 下面的 Interceptor,表示对特定的请求进行拦截 -->  
            <bean class="com.hit.interceptor.LoginInterceptor"/>  
        </mvc:interceptor>  
    </mvc:interceptors>  
    

    在 Spring 的XML 配置文件中,我们可以通过mvc:interceptors标签声明一系列的拦截器,例如:

    <mvc:interceptors>
        <bean class="com.hit.interceptor.ContextInterceptor"/>
        <bean class="com.hit.interceptor.LoginInterceptor"/>
        <bean class="com.hit.interceptor.WrongCodeInterceptor"/>
    </mvc:interceptors>
    

    如上所示,这些拦截器就构成了一个拦截器链,或者称之为拦截器栈。这些拦截器的执行顺序是按声明的先后顺序执行的,即:先声明的拦截器先执行,后声明的拦截器后执行。在mvc:interceptors标签下声明interceptor标签主要有两种方式:

    • 直接定义一个Interceptor实现类的bean对象,使用这种方式声明的Interceptor拦截器将会对所有的请求进行拦截;
    • 使用mvc:interceptor标签进行声明,使用这种方式进行声明的Interceptor可以通过mvc:mapping子标签来定义需要进行拦截的请求路径。

    此外,由于拦截器是 AOP 编程思想的典型应用,也就意味着我们可以“切”到具体的“面”进行某些操作。例如,

    <bean id="WrongCodeInterceptor" class="com.hit.interceptor.WrongCodeInterceptor">
    		<property name="userName" value="user-module"></property>
    </bean>
    	
    <bean id="loginInterceptor" class="com.hit.interceptor.LoginInterceptor">
    	<property name="excludePackages">
    	   <list>
    		  <value>com.hit.user.exception</value>
    		  <value>com.hit.order.exception</value>
    	   </list>
    	</property>
    </bean>
    	
    <aop:config>
    	<aop:advisor advice-ref="WrongCodeInterceptor" pointcut="execution(* com.hit.*.demo..*.*(..)) " />
    	<aop:advisor advice-ref="loginInterceptor" pointcut="execution(* com.hit.*.demo..*.*(..))" />
    </aop:config>
    

    如上所示,我们实现了切入到“面”进行特定的拦截功能,其中pointcut表示“切入点”,advisor表示要注入到pointcut的代码。实际上,如果在多个拦截器配置中,pointcut表达式都相同,我们可以将其抽取出来,单独声明,然后通过pointcut-ref标签进行引用,这样可以稍微简化一些配置!

    除此之外,大家可能会对pointcut中的*符号有所疑惑,它是“通配符”,表示可以匹配该位置上的任何名称。当然,如果我们要想使用aop标签,就得先在配置文件中进行声明啦!最后,如果大家想进一步了解切入点pointcut表达式的话,可以参考博文「Spring 框架中切入点 pointcut 表达式的常用写法 」。


    参考文献:

    1. struts2使用AbstractInterceptor实现拦截器
    2. Spring AOP中Pointcut,dvice 和 Advisor三个概念介绍
    3. Java三大器之拦截器(Interceptor)的实现原理及代码示例
    4. SpringMVC中使用Interceptor拦截器
    5. Java过滤器与SpringMVC拦截器之间的关系与区别
    展开全文
  • Interceptor(拦截器)

    千次阅读 2018-12-20 15:18:30
    Interceptor(拦截器) 拦截器是AOP的一种实现。 实现拦截器步骤:1、定义 2、注册 HandlerInterceptorAdapter与WebMvcConfigurerAdapter更方便些,不需要实现所有方法。 HandlerInterceptor与WebMvcConfigurer...

    Interceptor(拦截器)

    拦截器是AOP实现的。

    实现拦截器步骤:1、定义  2、注册

    HandlerInterceptorAdapter与WebMvcConfigurerAdapter更方便些,不需要实现所有方法。

    HandlerInterceptor与WebMvcConfigurer则需要实现所有方法

     定义一个拦截器

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

    注册拦截器 

    @Configuration
    public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new TokenInterceptor()).addPathPatterns("/user/*").excludePathPatterns("/user/getone2");
        }
    }

    这样就添加了一个拦截器。 拦截除/user/getone2以外的与/user/*匹配的域名,比如会拦截/user/getone1、/user/getone3。

    (注:/user/test/test不拦截,/user/test/test匹配/user/*/*而不匹配/user/*)

     

     

    应用:

    1、用户是否存在。具体比如验证token在数据库中是否存在:不存在,表明用户不存在或登陆过期等,拒绝通过;存在,通过。

    2、整个系统字符集编码

    3、URL访问权限过滤

    4、过滤敏感词信息

    5、日志记录

    6、等等

     

     

     

    拦截器是AOP的一种实现,所以有多个拦截器顺序与AOP顺序是一样的。

    AOP详见:https://blog.csdn.net/sunshine_YG/article/details/82705170

    个人测试了三个拦截器,结果如下:

    拦截器顺序测试代码:

    public class Interceptor1 implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("=pre==="+this.getClass().getSimpleName());
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("=post==="+this.getClass().getSimpleName());
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("=after==="+this.getClass().getSimpleName());
        }
    }
    
    @Configuration
    public class MyWebMvcConfigurer implements WebMvcConfigurer {
        @Override
        public void configurePathMatch(PathMatchConfigurer configurer) {
    
        }
    
        @Override
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    
        }
    
        @Override
        public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
    
        }
    
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    
        }
    
        @Override
        public void addFormatters(FormatterRegistry registry) {
    
        }
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
    //        InterceptorRegistration registration = registry.addInterceptor(new TokenInterceptor());
    //        registration.addPathPatterns("/*");
            InterceptorRegistration interceptor = registry.addInterceptor(new Interceptor1());
            interceptor.addPathPatterns("/*");
            InterceptorRegistration interceptor2 = registry.addInterceptor(new Interceptor2());
            interceptor2.addPathPatterns("/*");
            InterceptorRegistration interceptor3 = registry.addInterceptor(new Interceptor3());
            interceptor3.addPathPatterns("/*");
        }
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
    
        }
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
    
        }
    
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
    
        }
    
        @Override
        public void configureViewResolvers(ViewResolverRegistry registry) {
    
        }
    
        @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    
        }
    
        @Override
        public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
    
        }
    
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    
        }
    
        @Override
        public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    
        }
    
        @Override
        public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
    
        }
    
        @Override
        public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
    
        }
    
        @Override
        public Validator getValidator() {
            return null;
        }
    
        @Override
        public MessageCodesResolver getMessageCodesResolver() {
            return null;
        }
    }
    

     

    展开全文
  • 拦截器Interceptor总结

    2017-07-21 22:04:43
    拦截器Interceptor总结 目录介绍 1.拦截器简介 2.拦截器的种类 3.拦截器种类选择 4.解决实际问题:如何避免登录过期问题?1.拦截器简介 官方定义 Interceptors area powerful mechanism that can monitor, ...

    拦截器Interceptor总结
    目录介绍
    1.拦截器简介
    2.拦截器的种类
    3.拦截器种类选择
    4.解决实际问题:如何避免登录过期问题?

    1.拦截器简介
    官方定义
    Interceptors area powerful mechanism that can monitor, rewrite, and retry calls.
    拦截器可以用来转换,重试,重写请求的机制。

    OkHttp的 Interceptor 就如同名称「拦截器」一样,拦截你的 Request 做一些你想做的事情再送出去。例如:
    1.自动加上使用者目前使用的语言送出去取得对应语言的回传内容。
    2.将 Request 计算出这个 Request 的 sigunature 再附加上送出去。

    拦截器是 OkHttp 提供的对 HTTP 请求和响应进行统一处理的强大机制。拦截器在实现和使用上类似于 Servlet 规范中的过滤器。多个拦截器可以链接起来,形成一个链条。拦截器会按照在链条上的顺序依次执行。 拦截器在执行时,可以先对请求的 Request 对象进行修改;再得到响应的 Response 对象之后,可以进行修改之后再返回。
    Interceptor 接口只包含一个方法 intercept,其参数是 Chain 对象。Chain 对象表示的是当前的拦截器链条。通过 Chain 的 request 方法可以获取到当前的 Request 对象。在使用完 Request 对象之后,通过 Chain 对象的 proceed 方法来继续拦截器链条的执行。当执行完成之后,可以对得到的 Response 对象进行额外的处理。

    2.拦截器种类
    在 okHttp 中分成两种:
    Application Interceptor
    Network Interceptor Application Interceptor 是会可以被 cache 起来的

    Image.png

    OkHttp 中的拦截器分成应用和网络拦截器两种
    应用拦截器对于每个 HTTP 响应都只会调用一次,可以通过不调用 Chain.proceed 方法来终止请求,也可以通过多次调用 Chain.proceed 方法来进行重试。
    网络拦截器对于调用执行中的自动重定向和重试所产生的响应也会被调用,而如果响应来自缓存,则不会被调用。

    添加应用和网络拦截器

    - client.interceptors().add(new LoggingInterceptor());             //添加应用拦截器
    - client.networkInterceptors().add(new LoggingInterceptor());      //添加网络拦截器

    3.拦截器选择
    3.1 应用拦截器

    不需要担心中间过程的响应,如重定向和重试.
    总是只调用一次,即使HTTP响应是从缓存中获取.
    观察应用程序的初衷. 不关心OkHttp注入的头信息如: If-None-Match.
    允许短路而不调用 Chain.proceed(),即中止调用.
    允许重试,使 Chain.proceed()调用多次.

    3.2 网络拦截器

    能够操作中间过程的响应,如重定向和重试.
    当网络短路而返回缓存响应时不被调用.
    只观察在网络上传输的数据.
    携带请求来访问连接.

    4.解决实际问题:如何避免登录过期问题?

    public class NewSeedInterceptor implements Interceptor {
    
        @Override
        public Response intercept(Chain chain) throws IOException {
            String name = SPUtils.getInstance(Constants.NEW_SEED).getString(Constants.name, Constants.NAME);
            String pwd = SPUtils.getInstance(Constants.NEW_SEED).getString(Constants.pwd, Constants.PWD);
            String smsCode = SPUtils.getInstance(Constants.NEW_SEED).getString(Constants.code, Constants.CODE);
            String from = SPUtils.getInstance(Constants.NEW_SEED).getString(Constants.uForm, "0");
            int uFrom = Integer.parseInt(from);
    
            Request req = chain.request();
            Request request = req.newBuilder()
                    .addHeader("Cookie", ApiConstants.COOKIE + Constants.sid)
                    .addHeader("apptype", "2")
                    .build();
            Response response = chain.proceed(request);
    
            if (response.code()==200 && response.body()!=null) {
                Constants.string = response.body().string();
                if(AppCommentUtils.isGoodJson(Constants.string)){
                    if (Constants.string.contains("{") && Constants.string.contains("}") && !Constants.string.contains("<html>")) {
                        int code = new Gson().fromJson(Constants.string, BaseBean.class).getCode();
                        if (code == -1) {
                            if (name != null && name.length()>0 && pwd != null && pwd.length()>0) {
                                if (uFrom == 0) {              //手机号直接登录
                                    Constants.sid = NewSeedUtils.getNewSid(name, pwd, uFrom + "");
                                    Log.i("sid值手机",Constants.sid+"");
                                } else if (uFrom == 11) {      //sms登录
                                    Constants.sid = NewSeedUtils.getNewSidSms(name, smsCode, uFrom + "");
                                    Log.i("sid值手机",Constants.sid+"");
                                } else {                        //第三方登录
                                    Constants.sid = NewSeedUtils.getNewSidOther(name, pwd, uFrom + "");
                                    Log.i("sid值第三方",Constants.sid+"");
                                }
                            }
                        }
                    }
                }
            }
            return response;
        }
    }
    展开全文
  • 一、引言 本来想记录一下关于用户...关于Interceptor解决权限和菜单管理的问题,在放在下一篇写吧,就酱紫。 二、区别 1、过滤器(Filter) 首先说一下Filter的使用地方,我们在配置web.x...

    一、引言

    本来想记录一下关于用户登陆和登陆之后的权限管理、菜单管理的问题,想到解决这个问题用到Interceptor,但想到了Interceptor,就想到了Filter,于是就想说一下它们的执行顺序和区别。关于Interceptor解决权限和菜单管理的问题,在放在下一篇写吧,就酱紫。

    二、区别

    1、过滤器(Filter)

    首先说一下Filter的使用地方,我们在配置web.xml时,总会配置下面一段设置字符编码,不然会导致乱码问题:

    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <servlet-name>/*</servlet-name>
    </filter-mapping>
    

    配置这个地方的目的,是让所有的请求都需要进行字符编码的设置,下面来介绍一下Filter。

    (1)过滤器(Filter):它依赖于servlet容器。在实现上,基于函数回调,它可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的,是用来做一些过滤操作,获取我们想要获取的数据,比如:在Javaweb中,对传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者Controller进行业务逻辑操作。通常用的场景是:在过滤器中修改字符编码(CharacterEncodingFilter)、在过滤器中修改HttpServletRequest的一些参数(XSSFilter(自定义过滤器)),如:过滤低俗文字、危险字符等。

    2、拦截器(Interceptor)

    拦截器的配置一般在SpringMVC的配置文件中,使用Interceptors标签,具体配置如下:

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.scorpios.atcrowdfunding.web.LoginInterceptor"></bean>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.scorpios.atcrowdfunding.web.AuthInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
    

    (2)拦截器(Interceptor):它依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。

    三、代码


    下面在一个项目中我们使用既有多个过滤器,又有多个拦截器,并观察它们的执行顺序:
    (1)第一个过滤器:

    public class TestFilter1 implements Filter {  
      
    		@Override
      	    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {  
            //在DispatcherServlet之前执行  
    		System.out.println("############TestFilter1 doFilterInternal executed############");  
            filterChain.doFilter(request, response);  
            //在视图页面返回给客户端之前执行,但是执行顺序在Interceptor之后  
            System.out.println("############TestFilter1 doFilter after############");  
        }  
    }  
    

    (2)第二个过滤器:

    public class TestFilter2 implements Filter {  
     
    	@Override
        protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {  
    	    //在DispatcherServlet之前执行  
            System.out.println("############TestFilter2 doFilterInternal executed############");  
            filterChain.doFilter(request, response);  
            //在视图页面返回给客户端之前执行,但是执行顺序在Interceptor之后 
            System.out.println("############TestFilter2 doFilter after############");  
        }  
    }  
    

    (3)在web.xml中注册这两个过滤器:

    	<!-- 自定义过滤器:testFilter1 -->   
    	   <filter>  
    	        <filter-name>testFilter1</filter-name>  
    	        <filter-class>com.scorpios.filter.TestFilter1</filter-class>  
    	    </filter>  
    	    <filter-mapping>  
    	        <filter-name>testFilter1</filter-name>  
    	        <url-pattern>/*</url-pattern>  
    	    </filter-mapping>  
    	    <!-- 自定义过滤器:testFilter2 -->   
    	   <filter>  
    	        <filter-name>testFilter2</filter-name>  
    	        <filter-class>com.scorpios.filter.TestFilter2</filter-class>  
    	    </filter>  
    	    <filter-mapping>  
    	        <filter-name>testFilter2</filter-name>  
    	        <url-pattern>/*</url-pattern>  
    	    </filter-mapping>  
    

    再定义两个拦截器:
    (4)第一个拦截器:

    public class BaseInterceptor implements HandlerInterceptor{  
         
        /** 
         * 在DispatcherServlet之前执行 
         * */  
        public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {  
            System.out.println("************BaseInterceptor preHandle executed**********");  
            return true;  
        }  
     
        /** 
         * 在controller执行之后的DispatcherServlet之后执行 
         * */  
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {  
            System.out.println("************BaseInterceptor postHandle executed**********");  
        }  
         
        /** 
         * 在页面渲染完成返回给客户端之前执行 
         * */  
        public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)  
                throws Exception {  
            System.out.println("************BaseInterceptor afterCompletion executed**********");  
        }  
    }  
    

    (5)第二个拦截器:

    public class TestInterceptor implements HandlerInterceptor {  
     
        public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {  
            System.out.println("************TestInterceptor preHandle executed**********");  
            return true;  
        }  
     
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {  
            System.out.println("************TestInterceptor postHandle executed**********");  
        }  
     
        public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {  
            System.out.println("************TestInterceptor afterCompletion executed**********");  
        }  
    }  
    

    (6)、在SpringMVC的配置文件中,加上拦截器的配置:

    	<!-- 拦截器 -->  
    	<mvc:interceptors>  
    	    <!-- 对所有请求都拦截,公共拦截器可以有多个 -->  
    	    <bean name="baseInterceptor" class="com.scorpios.interceptor.BaseInterceptor" />  
    		
    		<mvc:interceptor> 
    		    <!-- 对/test.html进行拦截 -->       
    	        <mvc:mapping path="/test.html"/>  
    	        <!-- 特定请求的拦截器只能有一个 -->  
    	        <bean class="com.scorpios.interceptor.TestInterceptor" />  
    	    </mvc:interceptor>  
    	</mvc:interceptors>  
    

    (7)、定义一个Controller控制器:

    package com.scorpios.controller;  
    import org.springframework.stereotype.Controller;  
    import org.springframework.web.bind.annotation.RequestMapping;  
    import org.springframework.web.servlet.ModelAndView;  
      
    @Controller  
    public class TestController {  
        @RequestMapping("/test")  
        public ModelAndView handleRequest(){  
            System.out.println("---------TestController executed--------");  
            return new ModelAndView("test");  
        }  
    }  
    

    (8)、测试结果:
    启动测试项目,地址如下:http://www.localhost:8080/demo,可以看到控制台中输出如下:
    这里写图片描述
    这就说明了过滤器的运行是依赖于servlet容器,跟springmvc等框架并没有关系。并且,多个过滤器的执行顺序跟xml文件中定义的先后关系有关。

    接着清空控制台,并访问:http://www.localhost:8080/demo/test,再次看控制台的输出:
    这里写图片描述
    从这个控制台打印输出,就可以很清晰地看到有多个拦截器和过滤器存在时的整个执行顺序了。当然,对于多个拦截器它们之间的执行顺序跟在SpringMVC的配置文件中定义的先后顺序有关。

    四、总结


    对于上述过滤器和拦截器的测试,可以得到如下结论:
    (1)、Filter需要在web.xml中配置,依赖于Servlet;
    (2)、Interceptor需要在SpringMVC中配置,依赖于框架;
    (3)、Filter的执行顺序在Interceptor之前,具体的流程见下图;
    这里写图片描述
    (4)、两者的本质区别:拦截器(Interceptor)是基于Java的反射机制,而过滤器(Filter)是基于函数回调。从灵活性上说拦截器功能更强大些,Filter能做的事情,都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类),太细的话,还是建议用interceptor。不过还是根据不同情况选择合适的。

    展开全文
  • postman 和 postman interceptor。亲测可用,里边有说明博客
  • Interceptor的使用和使用场景

    千次阅读 2018-06-03 19:27:28
    一、引言 在上一篇文章中,介绍了Interceptor和Filter的区别和执行顺序。我们可以知道Filter依赖于Servlet,而Interceptor依赖于SpringMVC框架,所以 二、介绍 三、代码 四、总结...
  • OkHttp3使用(三)-Interceptor

    千次阅读 2019-03-06 12:43:58
    本篇文章,我们继续介绍其Interceptor的用法。在OkHttp框架中,Interceptor算是其强大的原因所在。我们平时很多功能(如下载进度监听、缓存策略设置、日志打印等)都需要通过Interceptor来实现。 Interceptor介绍 我们...
  • 拦截器(Interceptors)

    千次阅读 2018-04-27 16:43:49
    拦截器的工作原理如上图,每一个Action请求都包装在一系列的拦截器的内部。拦截器可以在Action执行直线做相似的操作也...自定义一个拦截器需要三步:1 自定义一个实现Interceptor接口(或者继承自AbstractIntercep...
  • 过滤器与拦截器的区别 过滤器可以简单的理解为“取你所想取”,过滤器关注的是web请求;拦截器可以简单的理解为“拒你所想拒”,拦截器关注的是方法调用,比如拦截 敏感词汇。 4.1,拦截器是基于java反射机制来实现...
  • Java 里的拦截器是动态拦截 action 调用的对象。它提供了一种机制可以使开发者可以定义在一个 action 执行的前后执行的代码,也可以在一个 action 执行前阻止其执行,同时也提供了一种可以提取 action 中可重用部分...
  • MyBatis 插件之拦截器Interceptor

    万次阅读 多人点赞 2019-06-12 16:30:50
    在很多业务场景下我们需要去拦截sql,达到不入侵原有代码业务处理一些东西,比如:分页操作,数据权限过滤操作,SQL执行时间性能监控等等,这里我们就可以用到Mybatis的拦截器Interceptor 二.Mybatis核心对象介绍 ...
  • SpringMVC中使用Interceptor拦截器

    千次阅读 2015-12-20 00:44:32
    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那样子判断当前时间是否是...
  • 过滤器(Filter)和拦截器(Interceptor)的区别

    万次阅读 多人点赞 2018-05-11 11:57:52
    来自:http://www.cnblogs.com/luoyun/archive/2013/01/04/2844274.html过滤器(Filter)和拦截器(Interceptor)的区别Filter介绍 Filter可以认为是Servlet的一种“加强版”,它主要用于对用户请求进行预处理,也可以...
  • Struts2拦截器原理 Struts2拦截器是在访问某个Action或Action的方法之前或之后实施拦截。在请求Struts2的Action时,Struts2会查找配置文件,并根据配置文件实例化相应的拦截器对象。Struts2拦截器配置 struts.xml...
  • AOP(面向切面编程) 面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,我们知道,面向对象的特点是继承、多态和封装。而封装就要求将功能分散到不同的对象中去,这在软件设计中往往称为职责分配。...
  • OkHttp 3.x 源码解析之Interceptor 拦截器

    千次阅读 2017-07-04 11:52:32
    OkHttp拦截器原理解析拦截器Java里的拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取...
  • 真正理解mybatis拦截器以及Interceptor和Plugin作用

    千次阅读 多人点赞 2019-03-01 11:43:46
    看了很多博客文章和,mybatis 的拦截器概念还是不能很好理解, 可能是因为自己基础不好或者理解方式和他人不同吧,所以决定自己花时间好好捋捋, 然后把理解后的总结记录下来,供他人参考,也许你们的理解和我也不同...
  • SpringBoot 拦截器(Interceptor)的使用

    万次阅读 2018-05-11 13:36:47
    过滤器 Filter 其实作用类似在最开始接触java 使用struts2的时候,里面都是filter后来springmvc时就用interceptor没太在意过区别,反正就是起检查作用的,仔细阅读 过滤器(filter)和拦截器interceptor)的区别...
  • SpringMVC的拦截器是主要作用是拦截用户请求到后台之间的请求,在进入后台之前可以对其进行权限认证和用户登录的限制。 1.定义拦截器; springmvc中拦截器中主要有两种方式:第一种是实现HandleInterceptor接口,...
  • Okhttp拦截器Interceptor学习和使用

    千次阅读 2018-11-25 18:20:53
    前言 前年的这个时候我们项目将网络框架替换为okhttp+retrofit ,然后我对 retrofit 源码进行了学习和分享,写了几篇相关的文章同时更新了项目的网络框架。 Android网络之Retrofit2.0使用和解析 ...
  • 【mybatis系列】自定义实现拦截器插件Interceptor

    千次阅读 多人点赞 2020-10-24 06:18:07
    拦截器应用场景: 类型 先说明Mybatis中可以被拦截的类型具体有以下四种: 1.Executor:拦截执行器的方法。 2.ParameterHandler:拦截参数的处理。 3.ResultHandler:拦截结果集的处理。 4.StatementHandl
  • Struts2 拦截器Interceptor )原理和配置

    万次阅读 多人点赞 2016-06-28 18:08:42
    一、Struts2拦截器原理: Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的 拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器。 ...
  • 一 简介(1)过滤:依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤实例只能在容器初始化时调用一次。使用过滤的目的是用来做一些过滤操作,获取我们想要获取的...
  • 通过上一章节的学习,我们明白了OkHttp拦截器链的调用原理,对拦截器有了初步的概念:OkHttp的网络请求,通过拦截器的链式调用,完成了与服务器端的数据交互
  • 使用过滤的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤中修改字符编码;在过滤中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等 关于过滤的一些用法可以参考我...
  • 过滤器拦截web访问url地址。 严格意义上讲,filter只是适用于web中,依赖于Servlet容器,利用Java的回调机制进行实现。 Filter过滤:和框架无关,可以控制最初的http请求,但是更细一点的类和方法控制不了。 ...
  • 本篇文章主要介绍了详解Retrofit Interceptor(拦截器) 拦截请求并做相关处理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Spring中使用Interceptor拦截器拦截请求

    万次阅读 2016-01-14 15:46:03
    本文实现一个基于Spring4.0的Interceptor拦截Controller请求的demo。更多的详细介绍在后续完善。 1、实现HandlerInterceptor接口 BaseInterceptor类HandlerInterceptor,并实现两个自定义的接口用来分发get和post...
  • SpringMVC中使用Interceptor拦截器顺序等

    万次阅读 2014-04-24 17:04:58
    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那样子判断当前时间是否是...
  • Mybatis采用责任链模式,通过动态代理组织多个拦截器(插件),通过这些拦截器可以改变Mybatis的...拦截器Interceptor)在 Mybatis 中被当做插件(plugin)对待,官方文档提供了 Executor,ParameterHandler,R...

空空如也

1 2 3 4 5 ... 20
收藏数 366,512
精华内容 146,604
关键字:

interceptor