springmvc----拦截器

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


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   回车

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

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

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



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

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  这里另一个请求,该请求不拦截。

结果。


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

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


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

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

首先定义多个拦截器。其中拦截器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
控制台打印结果。


因为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
控制台打印结果。

因为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
控制台打印结果。


因为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
控制台打印结果。


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

由上可以再得出结论,

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

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

拦截器主要做什么用,

比如校验某些session,

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

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

权限校验等等。


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

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

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值