SpringMVC 核心技术-拦截器

SpringMVC中的Interceptor拦截器是非常重要和相当有用的,它的主要作用是拦截指定的用户请求,并进行相应的预处理与后处理拦截器是全局的,可以对多个Controller做拦截。一个项目中可以有0个或多个拦截器, 他们在一起拦截用户的请求。拦截器常用在:用户登录处理,权限检查, 记录日志。

1、一个拦截器的执行

        实现步骤:

            1、创建Controller类

            2、创建一个普通类

                1)实现HandleInterceptor接口

                2)实现接口中的三个方法

            3、创建show页面

            4、创建Springmvc的配置文件

                1)组件扫描器,扫描@Controller注解

                2)声明拦截器,并指定拦截的请求uri地址

在创建普通类实现HandleInterceptor接口时,三个方法的详细讲解

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器方法preHandle()执行");
        return true;
}

preHandle:  预处理方法

参数:

         Object handler :被拦截的控制器对象myController

      返回值是Boolean:

               1、true:请求通过了拦截器的验证,可以执行处理器方法

        2、false:就是请求没有通过拦截器的验证,不能执行处理器方法

特点

        1、在控制器方法执行(myController的方法)之前先执行的 用户的请求首先到达此方法

        2、在这个方法中可以获取请求的信息验证请求是否符合要求 可以验证用户是否登录验证用户是否有权限访问某个链接地址(url) 。

            如果验证失败,可以截断请求,请求不能被处理 。

            如果验证成功,可以放行请求,此时控制器方法才能执行。

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        time = System.currentTimeMillis();
        if(modelAndView !=null){
            modelAndView.addObject("mydate",new Date());
            modelAndView.setViewName("other");
        }
        System.out.println("拦截器方法postHandle()执行");
}

   postHandle :后处理方法

  参数

           Object handler: 被拦截的处理对象myController

           ModelAndView :modelAndView:处理器方法的返回值

 特点:

       1、在处理器方法之后执行的(myController.dosome())

       2、可以获取处理器方法的返回值ModelAndView,可以修改ModelAndView中的数据和视图可以影响到最后执行结果。        

       3、它主要功能:就是对原来的执行结果执行第二次修正

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("postHandle到afterCompletion方法的执行时间:"+(System.currentTimeMillis()-time));
        System.out.println("拦截器的afterCompletion()执行了");
}

 afterCompletion:最后执行的方法

参数

       Object handler:被拦截的控制器对象myController

       Exception ex:程序发生的异常

特点:

       1、在请求处理完成后执行的,框架中规定是当你的视图处理完成后,对视图执行了forward就认为请求处理完成

       2、一般做资源回收的工作的,在程序请求的过程中创建了一些对象,在这里可以删除、回收

创建Springmvc的配置文件:

      声明拦截器:拦截器可以有0个或者多个

      声明第一个拦截器 一个interceptor就是一个拦截器

      mapping path="" 指定拦截的请求url地址

      path:就是uri地址,可以使用通配符 **

      **:表示任意字符,文件或者多级目录和目录中的文件  /user/**:这个以user开头就会拦截

      /user:前面的/是根目录

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        <context:component-scan base-package="cn.com.Ycy.Contrller"/>
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!-- 前缀名:视图文件的路径-->
            <property name="prefix" value="/WEB-INF/"/>
            <!-- 后缀名:视图文件的扩展名 -->
            <property name="suffix" value=".jsp"/>
        </bean>
        <!--  声明拦截器:拦截器可以有0个或者多个  -->
        <mvc:interceptors>
            <!-- 声明第一个拦截器 一个interceptor就是一个拦截器 -->
            <mvc:interceptor>
                <mvc:mapping path="/user/**"/>
                <bean class="cn.com.Ycy.handler.myInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>
</beans>

  代码演示:

  页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="textml; charset=UTF-8">
    <title>Title</title>
</head>
<body>
    <p>一个拦截器</p>
    <form action="user/some.do" method="post">
        姓名:<input type="text" name="name"><br/>
        年龄:<input type="text" name="age"><br/>
        <input type="submit" value="提交请求">
    </form>
</body>
</html>

Controller类 :

@RequestMapping(value = "/user")
@Controller
public class myController {
    @RequestMapping(value = "/some.do")
    public ModelAndView dosome(String name,String age)  {
        System.out.println("dosome方法执行");
        ModelAndView mv = new ModelAndView();
        mv.addObject("myname",name);
        mv.addObject("myage",age);
        mv.setViewName("show");
        return mv;
    }
}

拦截器类 :

public class myInterceptor implements HandlerInterceptor {
    private long time;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器方法preHandle()执行");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        time = System.currentTimeMillis();
        if(modelAndView !=null){
            modelAndView.addObject("mydate",new Date());
            modelAndView.setViewName("other");
        }
        System.out.println("拦截器方法postHandle()执行");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("postHandle到afterCompletion方法的执行时间:"+(System.currentTimeMillis()-time));
        System.out.println("拦截器的afterCompletion()执行了");
    }
}

拦截器中方法与处理器方法的执行顺序如下图 :

       2、多个拦截器的执行

       当有多个拦截器时,形成拦截器链。拦截器链的执行顺序,与其注册顺序一致。需要再 次强调一点的是,当某一个拦截器的 preHandle()方法返回 true 并被执行到时,会向一个专 门的方法栈中放入该拦截器的 afterCompletion()方法。

       多个拦截器的注册与执行:

        输出结果:

多个拦截器中方法与处理器方法的执行顺序如下图:

猜你喜欢

转载自blog.csdn.net/weixin_43725517/article/details/108269886
今日推荐