欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

springmvc----拦截器

程序员文章站 2022-07-09 18:14:22
...

点滴记载,点滴进步,愿自己更上一层楼。


springmvc的拦截器,只需要实现HandlerInterceptor接口即可,里面有三个方法需要注意。

public interface HandlerInterceptor {
    boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;

    void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;

    void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception;
}
以上为源码。其中

preHandle  为action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。

                   返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。

postHandle 为执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。

afterCompletion 为所有方法执行完毕后执行,可以统一处理某些异常,日志等等。


下面开始实现。

首先定义一个自己的拦截器。

package com.soft.intercepter;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by xuweiwei on 2017/8/21.
 */
public class MyIntercepter01 implements HandlerInterceptor {

    /**
     * action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
     *          返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
     */
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println(" preHandle start ...... ");
        String name=httpServletRequest.getParameter("name");
        String password = httpServletRequest.getParameter("password");
        // 一个简单的拦截器实现,如果输入的用户名,密码符合要求,则可以执行请求 返回true,否则不执行 返回true
        if("tom".equals(name)&&"123456".equals(password)){
            System.out.println(" login pass 执行登录...... ");
            return true;
        }
        System.out.println(" login fail 不执行登录操作 ...... ");
        return false;
    }

    /**
     * 执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
     */
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println(" postHandle start ...... ");
    }

    /**
     * 所有方法执行完毕后执行,可以统一处理某些异常,日志等等
     */
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println(" afterCompletion start ...... ");
    }
}

写一个controller   定义一个urlmapping  用于测试

package com.soft.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/**
 * Created by xuweiwei on 2017/8/21.
 */
@Controller
@RequestMapping(value="/login")
public class TestIntercepterController {

    /**
     * 测试拦截器用
     * @return ModelAndView
     */
    @RequestMapping(value="/userLogin")
    public ModelAndView testIntercepter(){
        System.out.println(" testIntercepter start ...... ");
        ModelAndView model = new ModelAndView();
        model.setViewName("test/testJsonParam");
        return model;
    }
}
配置拦截器到springmvc.xml   

    <!-- 配置拦截器 -->
    <mvc:interceptors>
        <!-- 配置自己定义的拦截器  可以配置多个 -->
        <mvc:interceptor>
            <!-- 配置拦截路径,即  什么样的请求才会进入该拦截器。
                 如果配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
            <mvc:mapping path="/login/*"/>
            <!-- 注入自己定义的拦截器 -->
            <bean class="com.soft.intercepter.MyIntercepter01"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
这个配置只是拦截特定的请求,如果请求中没有login 则不拦截。

测试,

浏览器输入   http://localhost:8080/login/userLogin   回车

控制台打印结果,因为没有用户名密码,登录校验通不过,所以不进行某些操作

springmvc----拦截器

浏览器输入  http://localhost:8080/login/userLogin?name=tom&password=123456  回车

控制台打印结果,用户名密码正确,执行用户请求。

springmvc----拦截器


再测试以前的一个请求。对应代码

package com.soft.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/**
 * Created by xuweiwei on 2017/8/19.
 */
@Controller
public class TestController {

    @RequestMapping(value = "/helloWorld")
    public ModelAndView helloWorld(){
        System.out.println(" helloWorld start ...... ");
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg","hello world!!!!!!!");
        modelAndView.setViewName("test/helloworld");
        return modelAndView;
    }
}


浏览器输入   http://localhost:8080/helloWorld  这里另一个请求,该请求不拦截。

结果。

springmvc----拦截器

可以看出拦截器并没有执行。

简单的一个拦截器就这些内容。


但是项目中不会只用到一个拦截器。但是多个拦截器也就是重复上面的步骤而已,需要注意的是,判断什么时候拦截操作,什么时候放行。

下面测试多个拦截器的执行顺序。

首先定义多个拦截器。其中拦截器06的preHandle不放行,拦截操作。

package com.soft.intercepter;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by xuweiwei on 2017/8/21.
 */
public class MyIntercepter02 implements HandlerInterceptor {

    /**
     * action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
     *          返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
     */
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("MyIntercepter02 preHandle start ...... ");
        return true;
    }

    /**
     * 执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
     */
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("MyIntercepter02 postHandle start ...... ");
    }

    /**
     * 所有方法执行完毕后执行,可以统一处理某些异常,日志等等
     */
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("MyIntercepter02 afterCompletion start ...... ");
    }
}


package com.soft.intercepter;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by xuweiwei on 2017/8/21.
 */
public class MyIntercepter03 implements HandlerInterceptor {

    /**
     * action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
     *          返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
     */
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("MyIntercepter03 preHandle start ...... ");
        return true;
    }

    /**
     * 执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
     */
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("MyIntercepter03 postHandle start ...... ");
    }

    /**
     * 所有方法执行完毕后执行,可以统一处理某些异常,日志等等
     */
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("MyIntercepter03 afterCompletion start ...... ");
    }
}
package com.soft.intercepter;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by xuweiwei on 2017/8/21.
 */
public class MyIntercepter04 implements HandlerInterceptor {

    /**
     * action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
     *          返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
     */
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("MyIntercepter04 preHandle start ...... ");
        return true;
    }

    /**
     * 执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
     */
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("MyIntercepter04 postHandle start ...... ");
    }

    /**
     * 所有方法执行完毕后执行,可以统一处理某些异常,日志等等
     */
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("MyIntercepter04 afterCompletion start ...... ");
    }
}

package com.soft.intercepter;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by xuweiwei on 2017/8/21.
 */
public class MyIntercepter05 implements HandlerInterceptor {

    /**
     * action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
     *          返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
     */
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("MyIntercepter05 preHandle start ...... ");
        return true;
    }

    /**
     * 执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
     */
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("MyIntercepter05 postHandle start ...... ");
    }

    /**
     * 所有方法执行完毕后执行,可以统一处理某些异常,日志等等
     */
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("MyIntercepter05 afterCompletion start ...... ");
    }
}

package com.soft.intercepter;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by xuweiwei on 2017/8/21.
 */
public class MyIntercepter06 implements HandlerInterceptor {

    /**
     * action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
     *          返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
     */
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("MyIntercepter06 preHandle start ...... ");
        return false;
    }

    /**
     * 执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
     */
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("MyIntercepter06 postHandle start ...... ");
    }

    /**
     * 所有方法执行完毕后执行,可以统一处理某些异常,日志等等
     */
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("MyIntercepter06 afterCompletion start ...... ");
    }
}

springmvc.xml中的配置拦截器,将这几个拦截器都配置成全局的,拦截所有请求,看执行顺序。拦截器那个配置在前先加载哪个。

所以这里的加载顺序为01 02 03 04 05 06 。

    <!-- 配置拦截器 -->
    <mvc:interceptors>
        <!-- 配置自己定义的拦截器  可以配置多个 -->
        <mvc:interceptor>
            <!-- 配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
            <mvc:mapping path="/login/*"/>
            <!-- 注入自己定义的拦截器 -->
            <bean class="com.soft.intercepter.MyIntercepter01"></bean>
        </mvc:interceptor>

        <!-- 配置自己定义的拦截器  可以配置多个 -->
        <mvc:interceptor>
            <!-- 配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
            <mvc:mapping path="/**"/>
            <!-- 注入自己定义的拦截器 -->
            <bean class="com.soft.intercepter.MyIntercepter02"></bean>
        </mvc:interceptor>

        <!-- 配置自己定义的拦截器  可以配置多个 -->
        <mvc:interceptor>
            <!-- 配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
            <mvc:mapping path="/**"/>
            <!-- 注入自己定义的拦截器 -->
            <bean class="com.soft.intercepter.MyIntercepter03"></bean>
        </mvc:interceptor>

        <!-- 配置自己定义的拦截器  可以配置多个 -->
        <mvc:interceptor>
            <!-- 配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
            <mvc:mapping path="/**"/>
            <!-- 注入自己定义的拦截器 -->
            <bean class="com.soft.intercepter.MyIntercepter04"></bean>
        </mvc:interceptor>

        <!-- 配置自己定义的拦截器  可以配置多个 -->
        <mvc:interceptor>
            <!-- 配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
            <mvc:mapping path="/**"/>
            <!-- 注入自己定义的拦截器 -->
            <bean class="com.soft.intercepter.MyIntercepter05"/>
        </mvc:interceptor>

        <!-- 配置自己定义的拦截器  可以配置多个 -->
        <mvc:interceptor>
            <!-- 配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
            <mvc:mapping path="/**"/>
            <!-- 注入自己定义的拦截器 -->
            <bean class="com.soft.intercepter.MyIntercepter06"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
浏览器请求:http://localhost:8080/helloWorld
控制台打印结果。

springmvc----拦截器
因为06拦截器不放行,

所以helloWorld action没有执行。

注意打印结果的顺序,preHandle先顺序打印,afterCompletion倒叙打印,并且postHandle没有执行,并且06的afterCompletion没有执行

接下类将06放行,05不放行。

 05拦截器

    /**
     * action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
     *          返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
     */
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("MyIntercepter05 preHandle start ...... ");
        return false;
    }
06拦截器

    /**
     * action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
     *          返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
     */
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("MyIntercepter06 preHandle start ...... ");
        return true;
    }

浏览器再次请求:http://localhost:8080/helloWorld
控制台打印结果。
springmvc----拦截器

因为05没有放行,所以helloWorld action仍然没有执行。

注意打印结果的顺序,preHandle先顺序打印,afterCompletion倒叙打印,并且postHandle没有执行。

并且 因为05不放行。06拦截器并没有执行。并且05的afterCompletion没有执行

接下来让04不放行,05 06都放行。

04拦截器

    /**
     * action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
     *          返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
     */
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("MyIntercepter04 preHandle start ...... ");
        return false;
    }
05拦截器

    /**
     * action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
     *          返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
     */
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("MyIntercepter05 preHandle start ...... ");
        return true;
    }
06拦截器不用动,刚才已经是放行状态了。

浏览器再次请求:http://localhost:8080/helloWorld
控制台打印结果。

springmvc----拦截器

因为04没有放行,所以helloWorld action仍然没有执行。

注意打印结果的顺序,preHandle先顺序打印,afterCompletion倒叙打印,并且postHandle没有执行。

并且 因为04不放行。05 06拦截器都没有执行。并且04的afterCompletion没有执行

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

到此可以得出结论,

1 同组的拦截器其中有一个不放行,后面的拦截器都不会执行,所以配置的时候应该将优先级高的拦截器放到前面,让其先执行,

2 同组的拦截器的preHandle是顺序执行,afterCompletion是倒叙执行。

3 同组的拦截器的某一个拦截器不放行,则它的afterCompletion也不会执行。

4 同组的拦截器只要有一个拦截器不放行,postHandle都不会执行。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面在看看拦截器都放行的结果。所有的preHandle的返回值都设为true

浏览器再次请求:http://localhost:8080/helloWorld
控制台打印结果。

springmvc----拦截器

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

由上可以再得出结论,

5 只有preHandle全部放行,postHandle才会执行,并且同样也是倒叙执行。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

拦截器主要做什么用,

比如校验某些session,

某些操作需要登录才能做,这时候需要做登录校验,

        如果没登录,调到登录页面,如果已经登录,则将登录信息重新放入session中,以防止过期。

权限校验等等。


拦截器到此结束,主要就是理解,以及如何配置全局拦截器, 如何配置某些请求的拦截器,以及如果写拦截器。

springmvc的基本要点差不多就这些了。

下节将分析源码,看springmvc的执行流程,怎么在代码中实现,以及今天的拦截器为什么回事这个执行过程。