【SpringMVC】| SpringMVC拦截器

news/2024/11/8 16:56:41/

目录

一:SpringMVC拦截器

1. 拦截器介绍

2. HandlerInterceptor接口分析

3. 自定义拦截器实现权限验证


一:SpringMVC拦截器

SpringMVC 中的 Interceptor 拦截器,它的主要作用是拦截指定的用户请求,并进行相应的预处理与后处理。其拦截的时间点在“处理器映射器根据用户提交的请求映射出了所要执行的处理器类,并且也找到了要执行该处理器类的处理器适配器,在处理器适配器执行处理器之前”。当然,在处理器映射器映射出所要执行的处理器类时,已经将拦截器与处理器组合为了一个处理器执行链,并返回给了中央调度器。

1. 拦截器介绍

(1)拦截器的应用场景 

针对请求和响应进行的额外的处理,在请求和响应的过程中添加预处理、后处理和最终处理;主要应用在以下场景当中:

①日志记录:记录请求信息的日志。

②权限检查:如登录检查。

③性能检测:检测方法的执行时间。

(2)拦截器的执行原理

①preHandle():在请求被处理之前进行操作;预处理
②postHandle():在请求被处理之后,但结果还没有渲染前进行操作,可以改变响应结果;后处理。
③afterCompletion:所有的请求响应结束后执行善后工作,清理对象、关闭资源 ;最终处理.。

(3)拦截器实现的两种方式

继承HandlerInterceptorAdapter【处理程序拦截适配器】的父类。
实现HandlerInterceptor【处理程序拦截器】接口,推荐使用实现接口的方式,因为继承是单继承的。

2. HandlerInterceptor接口分析

自定义拦截器,需要实现 HandlerInterceptor 接口;并且该接口中含有三个方法:

(1)preHandle

该方法在处理器方法执行之前执行。其返回值为 boolean类型,若为 true,则紧接着会执行处理器方法,且会将 afterCompletion()方法放入到一个专门的方法栈中等待执行。

(2)postHandle

该方法在处理器方法执行之后执行处理器方法若最终未被执行,则该方法不会执行。由于该方法是在处理器方法执行完后执行,且该方法参数中包含 ModelAndView,所以该方法可以修改处理器方法的处理结果数据,且可以修改跳转方向。

(3)afterCompletion

当preHandle()方法返回 true 时,会将该方法放到专门的方法栈中,等到对请求进行响应的所有工作完成之后才执行该方法。即该方法是在中央调度器渲染(数据填充)了响应页面之后执行的,此时对 ModelAndView 再操作也对响应无济于事。afterCompletion 最后执行的方法,清除资源,例如在 Controller 方法中加入数据等。

3. 自定义拦截器实现权限验证

(1)改造登录方法,在session中存储用户信息,用于进行权限验证

细节:一定要注意我们登录界面login.jsp跳转到的是/login还是/login.action;有没有带action直接决定我们后面拦截器exclude-mapping通行的路径带不带.action!

package com.bjpowernode.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;@Controller
public class WebInfAction {// 首先要跳转到登录页面@RequestMapping("/showLogin")public String submit(){System.out.println("访问login.jsp进行登录");return "login";}// 跳转到login.jsp后,在进行判断@RequestMapping("/login")public String login(String name, String pwd, HttpServletRequest request){ // 与前端保持一致,提交的数据自动吸过来if ("root".equalsIgnoreCase(name) && "123".equalsIgnoreCase(pwd)){// 在session中存储用户信息(把name存进去),用于权限验证request.getSession().setAttribute("user",name);return "main";}else {request.setAttribute("msg","用户名或者密码不正确");return "login";}}
}

(2)开发拦截器的功能,实现HandlerInterceptor接口,重写preHandle()方法

package com.bjpowernode.interceptor;import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class LoginInterceptor implements HandlerInterceptor {// 重写preHandle方法@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 是否登录的判断if(request.getSession().getAttribute("user") == null){ // 能取出来,表示登录过// 没有登录,打回到登录的页面,并给出提示request.setAttribute("msg","请先去登录!");request.getRequestDispatcher("WEB-INF/jsp/login.jsp").forward(request,response);return false;}// 如果登录过,就放行往下走return true;}
}

(3)在springmvc.xml文件中注册拦截器

拦截器中可以配置一个拦截器链,层层把关;这里我们只需要配置一个,总共配置三部分:

①映射要拦截的请求,一般设置为全部拦截。

②然后在设置要放行的请求。

③配置具体的拦截器实现功能的类。

    <!--注册拦截器--><mvc:interceptors><mvc:interceptor><!--映射要拦截的请求--><mvc:mapping path="/**"/><!--配置要放行的请求--><mvc:exclude-mapping path="/showLogin"/><!--登录的页面--><mvc:exclude-mapping path="/login"/><!--登录验证的页面--><!--配置具体的拦截器实现功能的类--><bean class="com.bjpowernode.interceptor.LoginInterceptor"/></mvc:interceptor></mvc:interceptors>

(4)测试:

在登录之前,我们还是知道showMain或者showIndex,直接访问是不能访问的,被拦截了

在成功登录之后,我们不关闭当前会话,重新开一个窗口, 直接访问就可以访问了


http://www.ppmy.cn/news/83232.html

相关文章

Spring Security 如何实现身份认证和授权?

Spring Security 是一个开源的安全框架&#xff0c;提供了基于权限的访问控制、身份认证、安全性事件发布等功能。在 Spring Boot 应用中使用 Spring Security 可以非常方便地实现用户身份认证和授权。 Spring Security 实现身份认证的主要方式是使用认证过滤器链&#xff0c;…

MySQL数据库中,在读已提交和可重复读这两个不同事务隔离级别下幻读的区别

目 录 1. 前 言1.1 并发事务存在的问题1.2 事务的隔离级别1.3 快照读和当前读 2. 不同事务隔离级别下幻读的区别2.1 读已提交下的幻读2.2 可重复读下的幻读2.2.1 情况一&#xff0c;无幻读2.2.2 情况二&#xff0c;有幻读2.2.3 情况三&#xff0c;有幻读 3. 小 结 1. 前 言 在…

基于 Prometheus 的 SLO告警实战

Prometheus是一个流行的开源监控系统&#xff0c;它可以帮助我们收集、存储和查询应用程序或系统的时间序列数据。在使用Prometheus进行监控时&#xff0c;通常需要根据服务水平指标&#xff08;Service Level Objectives&#xff0c;简称SLO&#xff09;来设置告警规则。 SLO…

linux学习[11]磁盘与文件系统(2):lsblkblkidpartedfdiskgdiskmkfs

文章目录 前言&#xff1a;1. 磁盘容量1.1 lsblk1.2 blkid1.3 parted 2. 磁盘分区2.1 fdisk/gdisk2.2 磁盘分区实例参考&#xff1a; 3. 磁盘格式化3.1 mkfs.xfs3.2 mkfs.ext43.3 mkfs.vfat 总结&#xff1a; 前言&#xff1a; 写了VMware的磁盘扩容之后&#xff0c;磁盘分区格…

标签派单系统架构设计

需求描述 项目背景 根据员工历史成单情况&#xff0c;计算员工对不同类型工单的转化能力。根据员工和工单标签匹配进行派单。 业务流程图 规则描述 每10分钟&#xff0c;分城进行一次派单&#xff0c;派单规则可能会动态删减&#xff0c;需要支持动态配置 工单标签说明 一…

Nginx Web页面缓存 Rsync远程同步

Nginx Web页面缓存 在http块中加配置&#xff1a; proxy_cache_path /data/nginx/cache levels1:2 keys_zonemy_cache:10m max_size10g inactive60m use_temp_pathoff ##################################### path&#xff1a;强制参数&#xff0c;指定缓存文件的存放路径 …

Spring 条件组件注解:`@Conditional` 与 `@ConditionalOnBean`

Spring 条件组件注解&#xff1a;Conditional 与 ConditionalOnBean 文章目录 Spring 条件组件注解&#xff1a;Conditional 与 ConditionalOnBean一、Conditional 基本使用0、条件组件是在非条件组件注册之后再进行注册的1、概述2、代码演示3、Conditional 的优缺点 二、Condi…

cpp 类成员函数delete this 会发生什么?

如题 this 简介: 每个非静态的类成员函数默认参数都会压栈一个this&#xff0c;它指向的是调用改成员函数的对象, 也是就className的object this 被隐含声明为 className* const this&#xff1b; 1.意味着不能改变this的指向2.this是个右值,不能取地址 ,不能&this 那我…