首页 > 其他分享 >[Spring]拦截器

[Spring]拦截器

时间:2024-09-22 14:01:11浏览次数:7  
标签:-------- 拦截器 admin Spring request System URL Interceptor

Interceptor 介绍

image

拦截器(Interceptor)同 Filter 过滤器一样,它俩都是面向切面编程——AOP 的具体实现(AOP切面编程只是一种编程思想而已)。
你可以使用 Interceptor 来执行某些任务,例如在 Controller 处理请求之前编写日志,添加或更新配置......
在 Spring中,当请求发送到 Controller 时,在被Controller处理之前,它必须经过 Interceptors(0或多个)。
Spring Interceptor是一个非常类似于Servlet Filter 的概念 。

Interceptor 作用

  1. 日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算 PV(Page View)等;
  2. 权限检查:如登录检测,进入处理器检测是否登录;
  3. 性能监控:通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间。(反向代理,如 Apache 也可以自动记录)
  4. 通用行为:读取 Cookie 得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取 Locale、Theme 信息等,只要是多个处理器都需要的即可使用拦截器实现。

自定义 Interceptor

如果你需要自定义 Interceptor 的话必须实现 org.springframework.web.servlet.HandlerInterceptor接口或继承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter类,并且需要重写下面下面 3 个方法:

  • preHandler(HttpServletRequest request, HttpServletResponse response, Object handler)方法在请求处理之前被调用。该方法在 Interceptor 类中最先执行,用来进行一些前置初始化操作或是对当前请求做预处理,也可以进行一些判断来决定请求是否要继续进行下去。该方法的返回至是 Boolean 类型,当它返回 false 时,表示请求结束,后续的 Interceptor 和 Controller 都不会再执行;当它返回为 true 时会继续调用下一个 Interceptor 的 preHandle 方法,如果已经是最后一个 Interceptor 的时候就会调用当前请求的 Controller 方法。

  • postHandler(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 方法在当前请求处理完成之后,也就是 Controller 方法调用之后执行,但是它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作。

  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法需要在当前对应的 Interceptor 类的 postHandler 方法返回值为 true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行。此方法主要用来进行资源清理。

接下来结合实际代码进行学习。
LogInterceptor 类:

public class LogInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        long startTime = System.currentTimeMillis();
        System.out.println("\n-------- LogInterception.preHandle --- ");
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("Start Time: " + System.currentTimeMillis());

        request.setAttribute("startTime", startTime);

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("\n-------- LogInterception.postHandle --- ");
        System.out.println("Request URL: " + request.getRequestURL());
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("\n-------- LogInterception.afterCompletion --- ");

        long startTime = (Long) request.getAttribute("startTime");
        long endTime = System.currentTimeMillis();
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("End Time: " + endTime);

        System.out.println("Time Taken: " + (endTime - startTime));
    }
}

OldLoginInterceptor 类:

public class OldLoginInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("\n-------- OldLoginInterceptor.preHandle --- ");
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("Sorry! This URL is no longer used, Redirect to /admin/login");

        response.sendRedirect(request.getContextPath()+ "/admin/login");
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("\n-------- OldLoginInterceptor.postHandle --- ");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("\n-------- OldLoginInterceptor.afterCompletion --- ");
    }
}

配置拦截器 :

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogInterceptor());
        registry.addInterceptor(new OldLoginInterceptor()).addPathPatterns("/admin/oldLogin");
        registry.addInterceptor(new AdminInterceptor()).addPathPatterns("/admin/*").excludePathPatterns("/admin/oldLogin");
    }
}

LogInterceptor 拦截器用于拦截所有请求;
OldLoginInterceptor 用来拦截链接 “ / admin / oldLogin”,它将重定向到新的 “ / admin / login”。;
AdminInterceptor用来拦截链接 “/admin/*”,除了链接 “ / admin / oldLogin”。

自定义 Controller 验证拦截器

@Controller
public class LoginController {

    @RequestMapping("/index")
    public String index(Model model){
        return "index";
    }

    @RequestMapping(value = "/admin/login")
    public String login(Model model){
        return "login";
    }
}

同时依赖 thymeleaf 模板构建两个页面。
index.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8" />
    <title>Spring Boot Mvc Interceptor example</title>
</head>

<body>
<div style="border: 1px solid #ccc;padding: 5px;margin-bottom:10px;">
    <a th:href="@{/}">Home</a>
       |   
    <a th:href="@{/admin/oldLogin}">/admin/oldLogin (OLD URL)</a>
</div>

<h3>Spring Boot Mvc Interceptor</h3>

<span style="color:blue;">Testing LogInterceptor</span>
<br/><br/>

See Log in Console..

</body>
</html>

login.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Spring Boot Mvc Interceptor example</title>
</head>
<body>

<div style="border: 1px solid #ccc;padding: 5px;margin-bottom:10px;">
    <a th:href="@{/}">Home</a>
       |   
    <a th:href="@{/admin/oldLogin}">/admin/oldLogin (OLD URL)</a>
</div>

<h3>This is Login Page</h3>

<span style="color:blue">Testing OldLoginInterceptor & AdminInterceptor</span>
<br/><br/>
See more info in the Console.

</body>

</html>

运行程序并测试效果
一切准备完毕,启动该项目。打开网址: http://localhost:8080/index

关于该请求在后台的执行过程,用图解的方式进行展示:

如果此时点击 /admin/oldLogin (OLD URL) 或者在网址栏输入:http://localhost:8080/admin/oldLogin

控制台打印结果:

-------- LogInterception.preHandle --- 
Request URL: http://localhost:8080/admin/oldLogin
Start Time: 1576329730709

-------- OldLoginInterceptor.preHandle --- 
Request URL: http://localhost:8080/admin/oldLogin
Sorry! This URL is no longer used, Redirect to /admin/login

-------- LogInterception.afterCompletion --- 
Request URL: http://localhost:8080/admin/oldLogin
End Time: 1576329730709
Time Taken: 0

-------- LogInterception.preHandle --- 
Request URL: http://localhost:8080/admin/login
Start Time: 1576329730716

-------- AdminInterceptor.preHandle --- 

-------- AdminInterceptor.postHandle --- 

-------- LogInterception.postHandle --- 
Request URL: http://localhost:8080/admin/login

-------- AdminInterceptor.afterCompletion --- 

-------- LogInterception.afterCompletion --- 
Request URL: http://localhost:8080/admin/login
End Time: 1576329730718
Time Taken: 2

image

标签:--------,拦截器,admin,Spring,request,System,URL,Interceptor
From: https://www.cnblogs.com/DCFV/p/18425224

相关文章

  • 美食探索家:Spring Boot校园美食分享网络
    第四章系统实现4.1前台首页功能模块校园周边美食探索及分享平台,在系统首页可以查看首页、美食鉴赏、我的好友、个人中心、后台管理等内容,如图4-1所示。图4-1前台首页功能界面图用户登录、用户注册,在用户注册页面可以填写用户名、姓名、手机、邮箱、身份证等详细内容进......
  • springAOP和spring事务
    AOP1.简介Aop面向切面编程:在开发中我们不能直接对已经设计好的代码进行修改(开放-封闭原则,对扩展开放,对修改封闭),解耦AOP的底层实现为动态代理*Target(目标对象):代理的目标对象*Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类*Joinpoint(连接点):所谓连接点是指那些......
  • 美食雷达:Spring Boot校园美食探索工具
    第二章系统分析2.1可行性分析可行性分析的目的是确定一个系统是否有必要开发、确定系统是否能以最小的代价实现。其工作主要有三个方面,分别是技术、经济和社会三方面的可行性。我会从这三个方面对网上校园周边美食探索及分享平台进行详细的分析。2.1.1技术可行性该系......
  • 【编程底层原理】彻底搞懂Spring是如何利用三级缓存来解决循环依赖问题的(一级缓存为
    一、整体推导思路为了彻底搞懂Spring是如何利用三级缓存来解决循环依赖问题的,要么去找三级缓存的设计者了解其设计的初衷,要么利用反推法来进行倒推(即一级缓存为啥不行,二级缓存为啥也不合适)。为了让大家能有一个更清晰的理解脉路,下面将先从反推法来介绍下一级缓存为啥不......
  • SpringBoot集成Sa-Token权限认证的学习
    一、前言Sa-Token是一个轻量级Java权限认证框架,主要解决登录认证、权限认证、Session会话、单点登录、OAuth2.0、微服务网关鉴权等一系列权限相关问题。它的API设计简单,易于上手,同时功能强大,能够满足多种复杂的权限认证需求。二、基本使用1.引入依赖<dependency> <groupId>cn.dev3......
  • 毕业设计|springboot产业园区智慧公寓管理系统-|免费|代码讲解
    收藏点赞不迷路 关注作者有好处编号:springboot547springboot产业园区智慧公寓管理系统-开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis工具:IDEA/Ecilpse、Navicat、Maven1.万字文档展示(部分)2.系统图片展示第5章系统详细设计这个环节需要使用前面的设......
  • 毕业设计|springboot人事管理系统论文-|免费|代码讲解
    收藏点赞不迷路 关注作者有好处编号:springboot350springboot人事管理系统论文-开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis工具:IDEA/Ecilpse、Navicat、Maven1.万字文档展示(部分)2.系统图片展示......
  • JAVA毕业设计|(免费)springboot农产品智慧物流系统包含文档代码讲解
    收藏点赞不迷路 关注作者有好处编号:springboot537springboot农产品智慧物流系统开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis工具:IDEA/Ecilpse、Navicat、Maven1.万字文档展示(部分)2.系统图片展示第5章系统详细设计......
  • JAVA毕业设计|(免费)springbootJAVA流浪动物救助平台-包含文档代码讲解
    收藏点赞不迷路 关注作者有好处编号:springboot530springbootJAVA流浪动物救助平台-开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis工具:IDEA/Ecilpse、Navicat、Maven1.万字文档展示(部分)2.系统图片展示第5章系统详细设计系统实现部分就是将系统分析,系......
  • JAVA毕业设计|(免费)Springboot和BS架构宠物健康咨询系统包含文档代码讲解
    收藏点赞不迷路 关注作者有好处编号:springboot509Springboot和BS架构宠物健康咨询系统开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis工具:IDEA/Ecilpse、Navicat、Maven1.万字文档展示(部分)2.系统图片展示第5章系统详细设计5.1管理员功能模块的实现5......