SpringMVC-拦截器

本文详细介绍了SpringMVC拦截器的概念、与过滤器的区别、如何定义和使用,以及通过登录验证的实战示例。深入理解了AOP在Spring MVC中的应用,包括HandlerInterceptor接口的实现和配置步骤。
摘要由CSDN通过智能技术生成

1. 拦截器

1.1 什么是拦截器

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

1.2 拦截器/过滤器

拦截器与过滤器的区别如下:

  • 拦截器是基于Java的反射机制,是AOP思想的具体应用,而过滤器是基于函数回调;
  • 拦截器不依赖于servlet容器,过滤器依赖于servlet容器;
  • 拦截器只能对action请求起作用,而过滤器几乎作用于所有的i请求;
  • 拦截器可以访问action上下文、栈里的对象,而过滤器不行;
  • 在action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调用一次;
  • 拦截器可以获取IOC容器的各个bean,而过滤器不行。

1.3 拦截器定义

在 Spring MVC 框架中定义一个拦截器需要对拦截器进行定义和配置,主要有以下 2 种方式。

  1. 通过实现 HandlerInterceptor接口或继承 HandlerInterceptor 接口的实现类(例如 HandlerInterceptorAdapter)来定义;
  2. 通过实现 WebRequestInterceptor 接口或继承 WebRequestInterceptor 接口的实现类来定义。

1.4 HandlerInterceptor接口

HandlerInterceptor接口主要包含三个抽象方法:

image-20211015204351708

preHandle: 在控制器的处理请求方法调用之前执行,其返回值表示是否中断后续操作,返回 true 表示继续向下执行,返回 false 表示中断后续操作。

**postHandle: **在控制器的处理请求方法调用之后,解析视图之前执行。

afterCompletion: 在控制器的处理请求方法执行完成后执行,即视图渲染结束之后执行,做清理工作。

该接口的实现类如下:

image-20211015204214378

2. 拦截器使用

2.1 前期准备

1️⃣ Step1:给项目添加Web;

2️⃣ Step2:修改web.xml文件,配置DispatcherServlet映射;

3️⃣ Step3:修改web.xml文件,通过init-param初始化参数,并指定SpringMV-Servlet配置文件

4️⃣ Step4:修改web.xml文件,配置启动级别;

5️⃣ Step5:修改web.xml文件,配置CharacterEncodingFilter映射;

6️⃣ Step6:修改SpringMV-Servlet配置文件,配置context自动扫描、mvc注解支持、禁止加载静态资源;

7️⃣ Step7:修改SpringMV-Servlet配置文件,配置视图解析器InternalResourceViewResolver;

2.2 实现抽象方法

public class MyInterceptor implements HandlerInterceptor {
    @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 {
        System.out.println("postHandle执行了!");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion执行了!");
    }
}

2.3 配置XML文件

在springmvc-servlet的配置文件中需要配置定义好的拦截器。

  • 所有的拦截器需要定义在<mvc:interceptors>标签中;
  • <mvc:mapping path="/**"/>:需要拦截的路径;
  • path:值为/**时表示拦截所有路径,例如/admin/**表示拦截/admin/下的所有路径;
  • path:值为/*时表示只拦截某包下的内容,例如/admin/*表示拦截/admin/下的路径, 而/admin/add/user则不会被拦截;
  • <bean class="xxx"/>:需要配置的拦截器实现类。
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="Config.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

2.4 编写Controller

@Controller
public class InterceptorTest {

    @RequestMapping("/Test")
    public String Test() {
        System.out.println("控制器中的方法执行了");
        return "test";
    }
}

2.5 测试输出

image-20211015211412067

image-20211015211428694

3. 拦截器实例

下面我们来完成一个用户登录验证的例子!

JSP页面包括:login.jspsuccess.jspusertest.jsp

Controller、Interceptor各一个:UserControllerUserInterceptor

3.1 前端页面

login.jsp:用于用户登录,action中为请求路径。

${pageContext.request.contextPath}:获取当前页面的绝对路径。

<h1>===这是登录页面===</h1>
<form action="${pageContext.request.contextPath}/user/Login">
    Username:<input type="text" name="username"> <br>
    Password:<input type="password" name="password"> <br>
    <input type="submit" value="Submit">
</form>

success.jsp:用户登录成功后进入该页面。

<h1>===这是成功页面===</h1>
<p>当前登录的用户为:${username}</p><br/>
<a href="${pageContext.request.contextPath}/user/Logout">退出登录</a>

usertest.jsp:该页面用于测试拦截器是否有效。

  • 若拦截器无效,可直接进入成功页面
  • 若拦截器有效,则会重定向到登录页面(在拦截器中实现)
<a href="${pageContext.request.contextPath}/user/GoLogin">前往登录</a>
<a href="${pageContext.request.contextPath}/user/GoSuccess">直接进入成功页面</a>

3.2 编写Controller

Controller中包含四个方法。

login方法说明:

  • 获取前端页面提交的username、password;
  • 当参数都不为空时进入成功页面,否则进入登录页面。
//登陆提交
@RequestMapping("/Login")
public String login(HttpSession session, String username, String password) throws Exception {
    // 向session记录用户身份信息
    System.out.println("当前登录用户:" + username);
    if (!username.trim().equals("") && !password.trim().equals("")) {
        session.setAttribute("username", username);
        return "success";
    }
    return "login";
}
//跳转到登陆页面
@RequestMapping("/GoLogin")
public String userLogin() {
    return "login";
}
//跳转到成功页面
@RequestMapping("/GoSuccess")
public String userSuccess() {
    return "success";
}
//退出登陆
@RequestMapping("/Logout")
public String logout(HttpSession session) {
    session.invalidate(); // 使session无效
    return "login";
}

3.3 编写Interceptor

拦截器应用于登录验证,所以只需实现preHandle方法即可。

public class UserInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 如果是登陆页面进来,则返回true
        System.out.println("URL:" + request.getRequestURI());
        if (request.getRequestURI().contains("Login")) {
            return true;
        }

        // 如果用户登录进来,则返回true
        if (request.getSession().getAttribute("username") != null){
            return true;
        }

        // 重定向到登录页面
        request.getRequestDispatcher("/jsp/login.jsp").forward(request,response);

        return false;
    }
}

3.4 配置Interceptor

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="Config.UserInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

3.5 测试输出

3.5.1 配置Interceptor前

动画1

3.5.2 配置Interceptor后

动画

4. 写在最后

实现HandlerInterceptor时,其中的方法非必须实现,因此需要根据需求实现即可。

 


❤️ END ❤️
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JOEL-T99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值