SpringMVC Day 10 : 拦截器

news2025/2/26 3:39:05

前言

拦截器是Spring MVC框架提供的一种强大的机制,用于在请求到达控制器之前或之后进行预处理和后处理。它可以拦截并处理请求,对请求进行必要的修改或验证,以及在请求返回给客户端之前进行额外的操作。拦截器可以帮助我们实现各种需求,如身份验证、日志记录、性能监控等。

在本篇博文中,我们将深入研究拦截器的概念、工作原理和使用方法。我们将学习如何创建和配置拦截器,以及如何将其应用于Spring MVC应用程序中。最后,我们还将探讨一些实际应用场景,并给出一些拦截器的最佳实践。

一、前期准备

1、新建项目,结构如下

2、导入依赖
    <dependencies>
    
        <!-- springmvc 依赖,会将spring的核心包一并添加进来 -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.23</version>
        </dependency>
     
 
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>
 
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.5</version>
        </dependency>
 
 
 
    </dependencies>
3、配置 web.xml 
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
 
 
</web-app>

 用于配置 Servlet 的映射和加载。在 Spring MVC 中,它用于配置 DispatcherServlet 的初始化和请求映射。

具体来说,这段配置的作用如下:

  1. 定义了一个名为 "dispatcher" 的 Servlet,并指定了 org.springframework.web.servlet.DispatcherServlet 作为其处理类。
  2. 设置了 load-on-startup 属性为 1,表示在应用启动时就加载该 Servlet。
  3. 使用 <servlet-mapping> 元素将 "dispatcher" Servlet 映射到所有的请求路径上(即 <url-pattern>/</url-pattern>),意味着所有的请求都会经过该 Servlet 进行处理。

 这段配置的作用是将所有的请求交给 DispatcherServlet 处理,并让它成为应用的核心控制器。DispatcherServlet 将根据请求的 URL 和其他配置信息,将请求分发给相应的处理器方法进行处理,然后返回响应结果。

4、新建 User 类
@Data
public class User {

    private String userName;
    private String password;

}
5、新建一个 LoginService 接口
public interface LoginService {

    /**
     * 登录认证
     * @param userName
     * @param password
     * @return
     */
    User auth(String userName,String password);

}
6、新建一个 LoginServiceImpl 实现类
@Service
public class LoginServiceImpl implements LoginService {
    @Override
    public User auth(String userName, String password) {

        if ("qiu".equals(userName) && "123".equals(password)){
            User user = new User();
            user.setUserName(userName);
            user.setPassword(password);
            return user;
        }
        throw new RuntimeException("账号密码错误");
    }
}

在业务类这里做一个简单的业务处理,判断输出的账号密码是否正确,然后抛出一个账号或密码错误的异常。

7、新建一个 index.html 页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>home page</h1>
</body>
</html>

 用于登录跳转的页面。

二、实现拦截器

1、编写一个 controller 
@RestController
@RequiredArgsConstructor
public class UserController {

    private final LoginService service;

    @PostMapping("/auth")
    public ResultVO login(String userName, String password, HttpSession session){
        User auth = service.auth(userName, password);
        session.setAttribute("user",auth);
        return new ResultVO();
    }

}

 该类中定义了一个名为UserController的控制器类,它只包含一个成员变量service和一个方法login。成员变量service是一个LoginService类型的对象,它通过构造函数注入到UserController中。方法login用于处理POST请求,并将用户名、密码和会话信息作为参数传入。在方法中,它调用service对象的auth方法进行登录验证,并将验证结果保存到会话中。最后,它返回一个ResultVO对象,这个对象可以被转换成JSON格式的数据并返回给客户端。

2、编写登录页面 login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
    <script src="js/JQuery文件.txt.js"></script>
</head>
<body>

<h1>用户登录</h1>
<form id="f1">
    账号:<input type="text" name="userName"/><br>
    密码:<input type="password" name="password"/><br>
    <input type="button" value="登录"/>
</form>
<script>
    $(function(){
        $(':button').on('click', function(){
            let formData = $('#f1').serialize();
            $.ajax({
                url: '../auth',
                type: 'post',
                data: formData,
                success: function (result) {
                    if(result.code === 200) {
                        location.href = 'index.html';
                    }
                },
                error:function (error) {
                    alert(error)
                }
            });
        });
    })
</script>

</body>
</html>

该页面包含一个表单,用户需要输入账号和密码进行登录。表单中的数据通过serialize()方法序列化为字符串,并在点击登录按钮时发送到服务器。

在脚本部分,使用jQuery的(function())方法来确保页面加载完成后再执行代码。当用户点击登录按钮时,使用(function())方法来确保页面加载完成后再执行代码。当用户点击登录按钮时,使用.ajax()方法发送POST请求到服务器的'../auth'路径,并将表单数据作为请求参数。成功回调函数中判断返回结果的状态码是否为200,如果是,则跳转到'index.html'页面;错误回调函数中显示错误信息。

总体来说,这段代码实现了一个简单的用户登录功能,通过使用jQuery库简化了AJAX请求的编写过程,并在成功或失败时给予用户相应的提示。

3、编写拦截器
/**
 * @Date 2023-10-27
 * @Author qiu
 * 认证拦截器
 * 拦截所有的请求,如果未登录则返回 401(未登录,未认证) 状态码
 */
@Slf4j
public class AuthInterceptor implements HandlerInterceptor {

    /**
     * 在调用 controller 的请求方法之前执行
     * 如果此方法返回 false ,则请求不会继续往下执行
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("执行 preHandle 方法");
        HttpSession session = request.getSession();
        // 如果 session 为 null 表示用户未登录
        if ( session.getAttribute("user") == null ){
            ResultVO resultVO = new ResultVO();
            // 设置 401 状态码
            resultVO.setCode(HttpStatus.UNAUTHORIZED.value());
            resultVO.setMessage("未登录,请登录!");
            response.setContentType("application/json;charset=utf-8");
            String json = new ObjectMapper().writeValueAsString(resultVO);
            response.getWriter().println(json);
            return false;
        }
        return true;
    }

    /**
     * 在调用 controller 方法之后,返回之前执行
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("执行 postHandle 方法");
    }

    /**
     * 调用 controller 方法并返回之后执行
     * (注意:只有在 preHandle 返回 TRUE ,才会执行)
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("执行 afterCompletion 方法");
    }
}

这段代码是一个认证拦截器的实现示例。拦截器是Spring MVC框架提供的一种机制,用于在请求到达控制器之前或之后进行预处理和后处理操作。

这个认证拦截器的作用是拦截所有的请求,在调用控制器方法之前进行认证操作。具体功能如下:

  1. preHandle方法:

    • 在调用控制器方法之前执行。
    • 首先获取请求的session对象。
    • 如果session中未存储用户信息(即用户未登录),则返回401状态码,并返回未登录提示信息。
    • 通过设置response的内容类型为application/json;charset=utf-8,将结果以JSON格式返回给客户端。
    • 如果preHandle方法返回false,则请求不会继续往下执行,即不会调用控制器方法;如果返回true,则请求会继续执行。
  2. postHandle方法:

    • 在调用控制器方法之后,返回之前执行。
    • 这个方法可以对请求的结果进行一些处理,比如修改ModelAndView对象的数据等。
  3. afterCompletion方法:

    • 在调用控制器方法并返回之后执行。
    • 注意,该方法只有在preHandle方法返回true的情况下才会执行。
    • 可以进行一些清理工作,比如释放资源等。

这个认证拦截器的主要作用是在请求到达控制器之前检查用户是否已登录,如果未登录,则返回401状态码。使用拦截器可以很方便地实现对请求的统一认证、授权等处理,提高应用程序的安全性和可维护性。

4、配置 dispatcher-servlet.xml
<?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
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd">


    <!-- 扫描 -->
    <context:component-scan base-package="edu.nf.ch10"/>
    <!-- mvc 注解驱动器 -->
    <mvc:annotation-driven/>
    <!-- 静态资源处理器 -->
    <mvc:default-servlet-handler/>
    <!-- 内部资源视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- 配置拦截器 -->
    <mvc:interceptors>
        <!-- 装配具体的拦截器 -->
        <mvc:interceptor>
            <!-- 设置哪些请求会经过这个拦截器 -->
            <mvc:mapping path="/**"/>
            <!-- 排除哪些请求不经过这个拦截器 -->
            <mvc:exclude-mapping path="/static/login.html"/>
            <mvc:exclude-mapping path="/auth"/>
            <mvc:exclude-mapping path="/static/js/**"/>
            <!-- 装配具体的拦截器 -->
            <bean class="edu.nf.ch10.interceptor.AuthInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>




</beans>

这段代码是一个Spring MVC配置文件,用于配置Spring MVC框架的相关组件和拦截器。

具体功能如下:

  1. component-scan:

    • 配置组件扫描的基础包路径,使得Spring能够自动扫描并装配标有注解的组件(比如控制器、服务等)。
  2. mvc:annotation-driven:

    • 启用Spring MVC的注解驱动,使得控制器类中的注解生效,如@RequestMapping、@ResponseBody等。
  3. mvc:default-servlet-handler:

    • 配置静态资源的处理,默认的Servlet将会处理静态资源请求,如.css、.js、.jpg等文件。
  4. InternalResourceViewResolver:

    • 配置内部资源视图解析器,用于将逻辑视图名解析为实际的物理视图地址。
    • 设置了视图前缀和后缀,例如将逻辑视图名"index"解析为"/WEB-INF/jsp/index.jsp"。
  5. mvc:interceptors:

    • 配置拦截器。
    • 在这个示例中,定义了一个具体的拦截器AuthInterceptor,并设置了哪些请求会经过该拦截器。
    • 使用mvc:mapping配置需要拦截的请求路径,使用mvc:exclude-mapping配置不需要拦截的请求路径。
    • 这里的配置表示除了/static/login.html、/auth和/static/js/**这些路径外,其他所有请求都会经过AuthInterceptor拦截器。

通过这个配置文件,你可以实现以下功能:

  1. 启用Spring MVC框架的注解驱动,使得控制器类中的注解生效。
  2. 配置静态资源的处理,让默认的Servlet处理静态资源请求。
  3. 配置内部资源视图解析器,将逻辑视图名解析为实际的物理视图地址。
  4. 配置拦截器,对请求进行拦截并进行相应的处理,比如认证、授权、日志记录等。

总之,这段配置文件用于配置Spring MVC框架的相关组件和拦截器,以便实现Web应用程序的功能和需求。

5、运行效果
1)非登录效果

 在未登录的时候,我们是不能进到 index.html 页面的,因为我们的拦截器对它进行了拦截,只能登录了才能进去。 

2)登录效果
 

 我们登录之后就可以跳转到首页了吧。

 

三、使用拦截器的好处

使用拦截器的好处包括:

  1. 统一处理:可以在拦截器中统一处理一些公共业务逻辑,比如权限校验、日志记录等,避免重复代码的出现。

  2. 粒度控制:可以根据具体的业务场景,选择拦截器拦截请求,实现粒度控制,从而更好地满足业务需求。

  3. 解耦合:通过拦截器可以将多个模块的功能解耦合,降低各组件之间的耦合度,提高代码可维护性和可扩展性。

  4. 提高安全性:通过拦截器可以对请求进行安全控制,比如防止SQL注入、XSS攻击等,提高Web应用系统的安全性。

  5. 性能优化:通过拦截器可以对请求进行缓存、预处理等操作,以提高Web应用系统的性能。

总之,使用拦截器可以帮助我们更好地管理请求,增强代码的可维护性和可读性,提高Web应用系统的安全性和性能。

四、gitee 案例

地址:ch10 · qiuqiu/SpringMVC - 码云 - 开源中国 (gitee.com) 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1158717.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文心一言4.0对比ChatGPT4.0有什么优势?

目录 总结 文心一言4.0的优势 文心一言4.0的劣势 免费分享使用工具 后话 生成式AI的困境 “不会问”“不会用”“不敢信” 为什么要出收费版本&#xff1f; 目前使用过国内的文心一言3.5和WPS AI&#xff0c;国外的ChatGPT4.0。 文心一言和其他国内产品相比&#xff0…

Windows 开启 Kerberos 的火狐 Firefox 浏览器访问yarn、hdfs

背景&#xff1a;类型为IPA或者MIT KDC&#xff0c;windows目前只支持 firefoxMIT Kerberos客户端的形式&#xff0c;其他windows端浏览器IE、chrome、edge&#xff0c;没有办法去调用MIT Kerberos Windows客户端的GSSAPI验证方式&#xff0c;所以均无法使用 Windows 开启 Kerb…

stm32 模拟I2C

目录 简介 I2C 物理层 协议层 ①②&#xff1a;起始信号和结束信号 ③ 应答和非应答信号 ④数据有效性 ⑤数据传输 ⑥空闲状态 简介 I2C 物理层 一个 I2C 总线两条线组成&#xff0c;一个双向串行数据线SDA用来表示数据&#xff0c;一个串行时钟线SCL用于数据收发同步…

进口跨境电商商城源码(海关179接口+支持多平台搭建+提供多终端支持)

海关179接口 进口跨境电商商城源码提供了与海关179接口的集成&#xff0c;实现了便捷的报关操作。海关179接口是跨境电商进口的关键链接&#xff0c;通过该接口可以快速准确地完成商品的报关手续。进口商可以通过商城源码直接与海关进行数据交互&#xff0c;减少了繁琐的人工操…

taro微信小程序不支持热重新的一种解决思路

使用taro开发我觉得是挺好的&#xff0c;但是也有一个缺点&#xff0c;就是暂时使用不了微信的热重载功能&#xff0c;每次更新代码之后&#xff0c;都要手动重新编译才可以看到效果&#xff0c;这就很麻烦了&#xff0c;所以一种解决思路就是先开发h5的页面&#xff0c;因为h5…

【力扣】2127. (分类讨论 + 拓扑排序)参加会议的最多员工数

【力扣】2127. &#xff08;分类讨论 拓扑排序&#xff09;参加会议的最多员工数 文章目录 【力扣】2127. &#xff08;分类讨论 拓扑排序&#xff09;参加会议的最多员工数1. 题目介绍2. 思路&#xff08;**分类讨论 拓扑排序**&#xff09;3. 解题代码4. Danger参考 1. 题…

为什么时间跟踪对企业和员工很重要?

时间是每个企业主最宝贵的资产。如果员工不能正确管理自己的时间&#xff0c;就会出现延误&#xff0c;项目也会超出预算。 为了让员工获得公平的时间补偿&#xff0c;就必须记录他们的工作时间。工时管理系统可以帮助企业和员工更好地组织工作、提高效率和生产力&#xff0c;…

100量子比特启动实用化算力标准!玻色量子重磅发布相干光量子计算机

2023年5月16日&#xff0c;北京玻色量子科技有限公司&#xff08;以下简称“玻色量子”&#xff09;在北京正大中心成功召开了2023年首场新品发布会&#xff0c;重磅发布了自研100量子比特相干光量子计算机——“天工量子大脑”。 就在3个月前&#xff0c;因“天工量子大脑”在…

redis 集群配置

1 . 存在的问题 单台redis容量限制&#xff0c;如何进行扩容&#xff1f;继续加内存、加硬件么&#xff1f;单台redis并发写量太大有性能瓶颈&#xff0c;如何解决&#xff1f;redis3.0中提供了集群可以解决这些问题。 2 . 什么是集群 redis集群是对redis的水平扩容&#xff…

Whisper 从0安装教程 windows

这里写自定义目录标题 Whisper 从0安装教程 windows安装过程安装python3.11安装Anaconda在Anaconda里面安装whisper安装 ffmpeg第一次运行whisper检查GPU 一些弯路 Whisper 从0安装教程 windows 因为需要把语音变成文字稿&#xff0c;问了做语言相关的朋友&#xff0c;决定使用…

基于51单片机的智能手机充电器设计

**单片机设计介绍&#xff0c;1660【毕设课设】基于51单片机和MAX1898的智能手机充电器设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 51单片机智能手机充电器设计介绍 51单片机智能手机充电器是一种可以实现智能快速充电的…

stm32中断

目录 简介 什么是NVIC 中断优先级 EXTI 简介 总结 hal库初始化代码 标准库初始化代码 简介 什么是中断&#xff1f;正常情况下&#xff0c;微处理器根据代码内容&#xff0c;按顺序执行指令。执行过程中&#xff0c;如果遇到其它紧急的事件需要处理&#xff0c;则先暂停当…

CodeWhisperer 初体验-手把手教导 给你飞一般的体验!

文章作者&#xff1a;燛衣 CodeWhisperer 有以下几个主要用途&#xff1a; 解决编程问题&#xff1a;CodeWhisperer 可以帮助您解决遇到的编程问题。您可以描述您的问题或需求&#xff0c;CodeWhisperer 将尽力提供相关的解决方案、代码示例或建议。无论您是遇到了语法错误、逻…

ardupilot开发 --- SLAM 篇

1. 视觉SLAM 1.1 深度相机的种类 结构光相机&#xff0c;如 Kinect1.0、RealSenseTOF相机&#xff0c;如 Kinect2.0双目相机&#xff0c;如 ZED详细参考&#xff1a;https://zhuanlan.zhihu.com/p/282776636 1.2 视觉SLAM算法 2D slam 与3D slam 应用场景有哪些不同&#x…

高通财报分析:恶劣环境将导致高通股价在财报后大幅下跌

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 总结&#xff1a; &#xff08;1&#xff09;根据我们的分析&#xff0c;高通(QCOM)的股价在上个季度下跌了近16%&#xff0c;预计在本季度财报后还将继续下跌。 &#xff08;2&#xff09;在恶劣的环境下&#xff0c;高通…

西门子精智触摸屏使用U盘下载程序时报错“出现严重错误,必须关机”处理办法

西门子精智触摸屏使用U盘下载程序时报错“出现严重错误,必须关机”处理办法 如下图所示,精智触摸屏使用U盘下载程序时报错: Application CTLPNL. EXE encountered a serious error and must shut down 出现这种情况时,可以尝试从以下几方面进行逐个排查: 断电重启,更换U盘…

知了汇智2024届“天府人才·校招行”启动,这些岗位急招...

知了汇智作为数字经济新业态下的产教融合服务型平台机构&#xff0c;大力构建企业与高校的交流平台&#xff0c;旗下全资子公司成都知聊人才服务有限公司&#xff0c;致力于为企业提供数字技术、数字营销方面的人才招聘、人才输送、人才定制等服务&#xff1b;为求职者提供个人…

三氧化二铁纳米片

&#xff08;西&#xff09;三氧化二铁纳米片 &#xff08;安&#xff09;名称&#xff1a;三氧化二铁纳米片 &#xff08;瑞&#xff09;CAS&#xff1a;1309-37-1 &#xff08;禧&#xff09;分子式&#xff1a;Fe2O3 &#xff08;生&#xff09;外观&#xff1a;白色粉末…

怎么让照片内存变小?三个方法轻松搞定!

让照片内存变小可以节省存储空间、提高传输速度、优化图片质量和降低流量消耗等&#xff0c;对于设备性能和用户体验都有积极的影响。下面介绍了三种简单有效的方法&#xff0c;一起来看看吧~ 方法一&#xff1a;通过嗨格式压缩大师压缩照片让内存变小 通过压缩照片&#xff0…

avi怎么转mp4?

avi怎么转mp4&#xff1f;如今市面上涌现了各种多样的视频格式&#xff0c;其中AVI作为一种音频视频交错格式&#xff0c;虽然使用较少但相对常见。它的优点在于占用空间较小&#xff0c;但画面质量并不是很出色。然而&#xff0c;AVI格式也存在一个明显的缺点&#xff0c;即兼…