十五、拦截器

目录

一、拦截器概述

1、什么是拦截器?

2、拦截器的定义

3、 拦截器的配置

二、拦截器的执行流程

1、单个拦截器的执行流程

2、多个拦截器的执行流程


在实际项目中,拦截器的使用是非常普遍的,例如在购物网站中通过拦截器可以拦截未登录的用户,禁止其购买商品,或者使用它来验证已登录用户是否有相应的操作权限等。在Struts 2框架中,拦截器是其重要的组成部分,而Spring MVC中也提供了拦截器功能,通过配置即可对请求进行拦截处理。本章将针对Spring MVC中拦截器的使用进行详细讲解。

一、拦截器概述

1、什么是拦截器?

Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。

2、拦截器的定义

 要使用Spring MVC中的拦截器,就需要对拦截器类进行定义和配置。通常拦截器类可以通过两种方式来定义。

以实现HandlerInterceptor接口方式为例,自定义拦截器类的代码如下:

 3、 拦截器的配置

 要使自定义的拦截器类生效,还需要在Spring MVC的配置文件中进行配置。

二、拦截器的执行流程

在运行程序时,拦截器的执行是有一定顺序的,该顺序与配置文件中所定义的拦截器的顺序相关

 1、单个拦截器的执行流程

如果在项目中只定义了一个拦截器,那么该拦截器在程序中的执行流程如图所示。

 (1)在Eclipse 中,创建一个名为chapter15的 Web项目,将Spring MVC程序运行所需JAR包复制到项目的lib目录中,并发布到类路径下。
(2)在 web.xml 中,配置Spring MVC的前端过滤器和初始化加载配置文件等信息。
(3)在src目录下,创建一个com.itheima.controller包,并在包中创建控制器类HelloController,

package com.itheima .controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@controller
public class HelloController{
    /**
    *页面跳转
    */
    @RequestMapping("/hello")
    public String Hello(){
    System.out.println ("Hello!");
    return "success";
    }
}

( 4 )在src目录下,创建一个 com.itheima.interceptor包,并在包中创建拦截器类CustomInterceptor。该类需要实现 HandlerInterceptor 接口,并且在实现方法中需要编写输出语句来输出信息

package com.itheima.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework,web.servlet. Mode1AndView;
    /**
    *实现了HandlerInterceptor接口的自定义拦截器类
    */
public class CustomInterceptor implements HandlerInterceptor{
    @Override
    public boolean preHandle(HttpServletRequest request,
        HttpServletResponse response, Object handler) throws Exception {
        System.out.println ("CustomInterceptor. . .preHandle");
        //对拦截的请求进行放行处理
        return true;
    }
    @Override
    public void postHandle(HttpservletReqguest request,
        HttpServletResponse response, Object handler,ModelAndView modelAndview) throws Exception{
        System.out.println("CustomInterceptor. . .postHandle");
    }
    @Override
    public void afterCompletion(HttpServletRequest request,
        HttpServletResponse response, Object handler,
        Exception ex) throws Exception {
        System.out.println("CustomInterceptor. . .afterCompletion");
    }
}

(5)在src目录下,创建并配置Spring MVC的配置文件

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd

        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

        <!--扫描注册controller  -->
        <context:component-scan base-package="com.itheima.controller"></context:component-scan>
   
        <!-- 视图解析器 -->
       <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
               <property name="prefix" value="/WEB-INF/jsp/"></property>
               <property name="suffix" value=".jsp"></property>
       </bean>
       
       <!--配置拦截器  -->
       <mvc:interceptors>
                  <!--使用bean直接定义在<mvc:interceptors>下面的拦截器将拦截所有请求-->
                   <bean class="com.itheima.interceptor.LoginInterceptor"></bean>
       </mvc:interceptors>       
 </beans>

(6)在WEB-INF目录下,创建一个 jsp文件夹,并在该文件夹中创建一个页面文件success.jsp,然后在页面文件的<body>元素内编写任意显示信息,如“ok”。
(7)将项目发布到Tomcat 服务器并启动,在浏览器中访问地址http:/localhost:8080/chapter15/hello,程序正确执行后,浏览器会跳转到success.,jsp 页面,此时控制台的输出结果如图所示。

从图可以看出,程序先执行了拦截器类中的preHandle()方法,然后执行了控制器中的 Hello()方法,最后分别执行了拦截器类中的 postHandle()方法 afterCompletion()方法。这与上文所描述的单个拦截器的执行顺序是一致的。

2、多个拦截器的执行流程

多个拦截器(假设有两个拦截器Interceptor1和Interceptor2,并且在配置文件中, Interceptor1拦截器配置在前),在程序中的执行流程如下图所示:

为了验证上述描述,下面通过修改单个拦截器的案例来演示多个拦截器的执行,具体步骤如下。
(1)在com.itheima.interceptor包中,创建两个拦截器类Interceptor1和 Interceptor2,这两个拦截器类均实现了HandlerInterceptor接口,并重写其中的方法,

package com.itheima.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework,web.servlet. Mode1AndView;
    /**
    *以实现接口的方式定义拦截器
    */
public class Interceptor1 implements HandlerInterceptor{
    @Override
    public boolean preHandle(HttpServletRequest request,
        HttpServletResponse response, Object handler) throws Exception {
        System.out.println ("Interceptor1. . .preHandle");
        //对拦截的请求进行放行处理
        return true;
    }
    @Override
    public void postHandle(HttpservletReqguest request,
        HttpServletResponse response, Object handler,ModelAndView modelAndview) throws Exception{
        System.out.println("Interceptor1. . .postHandle");
    }
    @Override
    public void afterCompletion(HttpServletRequest request,
        HttpServletResponse response, Object handler,
        Exception ex) throws Exception {
        System.out.println("Interceptor1. . .afterCompletion");
    }
}

package com.itheima.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework,web.servlet. Mode1AndView;
    /**
    *以实现接口的方式定义拦截器
    */
public class Interceptor2 implements HandlerInterceptor{
    @Override
    public boolean preHandle(HttpServletRequest request,
        HttpServletResponse response, Object handler) throws Exception {
        System.out.println ("Interceptor2. . .preHandle");
        //对拦截的请求进行放行处理
        return true;
    }
    @Override
    public void postHandle(HttpservletReqguest request,
        HttpServletResponse response, Object handler,ModelAndView modelAndview) throws Exception{
        System.out.println("Interceptor2. . .postHandle");
    }
    @Override
    public void afterCompletion(HttpServletRequest request,
        HttpServletResponse response, Object handler,
        Exception ex) throws Exception {
        System.out.println("Interceptor2. . .afterCompletion");
    }
}

 (2)在配置文件springmvc-config.xml 中的<mvc:interceptors>元素内配置上面所定义的两个拦截器,配置代码如下所示。


 <!-- 配置多个拦截器 -->
<mvc:interceptors>
            <!--配置第一个拦截器 -->
            <mvc:interceptor>
                <!--配置拦截器作用的路径-->
                <mvc:mapping path="/**"/>
                <!--定义在<mvc:interceptor>下面的表示匹配指定路径的请求才进行拦截的-->
                <bean class="com.itheima.interceptor.Interceptor1"></bean>
            </mvc:interceptor>

            
            <!--配置第2个拦截器 -->
            <mvc:interceptor>
                <!--配置拦截器作用的路径-->
                <mvc:mapping path="/hello"/>
                <!--对应的拦截器的类 -->
                <bean class="com.itheima.interceptor.Interceptor2"></bean>
            </mvc:interceptor>
</mvc:interceptors> 

在上述拦截器的配置代码中,第一个拦截器会作用于所有路径下的请求,而第二个拦截器会作用于以“/hello”结尾的请求。
为了不影响程序的输出结果,可将上一小节案例中所配置的 CustomInterceptor 的拦截器配置注释掉。
( 3)发布项目到-Tomcat 服务器并启动,在浏览器中访问地址 http:/localhost.8080/chapter15/hello,控制台中输出的信息如图所示。

 从图可以看出,程序先执行了前两个拦截器类中的preHandle()方法,这两个方法的执行顺序与配置文件中定义的顺序相同;然后执行了控制器类中的 Hello()方法;最后执行了两个拦截器类中的postHandle()方法和afterCompletion()方法,且这两个方法的执行顺序与配置文件中所定义的拦截器顺序相反。

对拦截器类Interceptor1或者Interceptor2中标红信息,修改为return false,会有不同的结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值