当前位置:首页 > Java技术 > SpringBoot之HandlerInterceptorAdapter

SpringBoot之HandlerInterceptorAdapter

2022年08月06日 01:36:48Java技术8

 

在SpringBoot中我们可以使用HandlerInterceptorAdapter这个适配器来实现自己的拦截器。这样就可以拦截所有的请求并做相应的处理。

应用场景

  • 日志记录,可以记录请求信息的日志,以便进行信息监控、信息统计等。
  • 权限检查:如登陆检测,进入处理器检测是否登陆,如果没有直接返回到登陆页面。
  • 性能监控:典型的是慢日志。

在HandlerInterceptorAdapter中主要提供了以下的方法:
preHandle:在方法被调用前执行。在该方法中可以做类似校验的功能。如果返回true,则继续调用下一个拦截器。如果返回false,则中断执行,也就是说我们想调用的方法 不会被执行,但是你可以修改response为你想要的响应。
postHandle:在方法执行后调用。
afterCompletion:在整个请求处理完毕后进行回调,也就是说视图渲染完毕或者调用方已经拿到响应。

在HandlerInterceptorAdapter中主要提供了以下的方法:

  • preHandle:在方法被调用前执行。在该方法中可以做类似校验的功能。如果返回true,则继续调用下一个拦截器。如果返回false,则中断执行,也就是说我们想调用的方法 不会被执行,但是你可以修改response为你想要的响应。
  • postHandle:在方法执行后调用。
  • afterCompletion:在整个请求处理完毕后进行回调,也就是说视图渲染完毕或者调用方已经拿到响应。

HandlerInterceptor

SpringBoot之HandlerInterceptorAdapter _ JavaClub全栈架构师技术笔记

拦截器适配器HandlerInterceptorAdapter

public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {

   /**
    * This implementation always returns {@code true}.
    */
   @Override
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
         throws Exception {

      return true;
   }

   /**
    * This implementation is empty.
    */
   @Override
   public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
         @Nullable ModelAndView modelAndView) throws Exception {
   }

   /**
    * This implementation is empty.
    */
   @Override
   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
         @Nullable Exception ex) throws Exception {
   }

   /**
    * This implementation is empty.
    */
   @Override
   public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response,
         Object handler) throws Exception {
   }

}

有时候我们可能只需要实现三个回调方法中的某一个,如果实现HandlerInterceptor接口的话,三个方法必须实现,不管你需不需要,此时spring提供了一个HandlerInterceptorAdapter适配器(种适配器设计模式的实现),允许我们只实现需要的回调方法。
这样在我们业务中比如要记录系统日志,日志肯定是在afterCompletion之后记录的,否则中途失败了,也记录了,那就扯淡了。一定是程序正常跑完后,我们记录下那些对数据库做个增删改的操作日志进数据库。所以我们只需要继承HandlerInterceptorAdapter,并重写afterCompletion一个方法即可,因为preHandle默认是true。

运行流程总结如下:

  1. 拦截器执行顺序是按照Spring配置文件中定义的顺序而定的。
  2. 会先按照顺序执行所有拦截器的preHandle方法,一直遇到return false为止,比如第二个preHandle方法是return false,则第三个以及以后所有拦截器都不会执行。若都是return true,则按顺序加载完preHandle方法。
  3. 然后执行主方法(自己的controller接口),若中间抛出异常,则跟return false效果一致,不会继续执行postHandle,只会倒序执行afterCompletion方法。
  4. 在主方法执行完业务逻辑(页面还未渲染数据)时,按倒序执行postHandle方法。若第三个拦截器的preHandle方法return false,则会执行第二个和第一个的postHandle方法和afterCompletion(postHandle都执行完才会执行这个,也就是页面渲染完数据后,执行after进行清理工作)方法。(postHandle和afterCompletion都是倒序执行)

下面用一个demo来演示执行流程


定义一个类继承HandlerInterceptorAdapter,并重写方法


快捷键ctrl+o打开可以重写的方法面板选择

SpringBoot之HandlerInterceptorAdapter _ JavaClub全栈架构师技术笔记

package com.example.demo.config;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LogInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.err.println("================================== preHandle1 ===========================================");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.err.println("================================== postHandle1 ===========================================");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.err.println("================================== afterCompletion1 ===========================================");
    }

}

WebMvcConfigurerAdapter 抽象类是对WebMvcConfigurer接口的简单抽象(增加了一些默认实现),但在在SpringBoot2.0及Spring5.0中WebMvcConfigurerAdapter已被废弃 。官方推荐直接实现WebMvcConfigurer或者直接继承WebMvcConfigurationSupport

实现WebMvcConfigurer配置拦截器

package com.example.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogInterceptor());
    }
}

在控制器中写一个方法并访问

@ApiOperation(value = "test mybatis", notes = "")
@RequestMapping(value = "getuser", method = RequestMethod.GET)
public User getUser() {
    return userService.getUser();
}

会在控制台输出

SpringBoot之HandlerInterceptorAdapter _ JavaClub全栈架构师技术笔记

此时在加入一个拦截器,会按照配置的顺序执行,配置如下

package com.example.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogInterceptor());
        registry.addInterceptor(new LogInterceptor2());
    }
}

控制的输出反映了配置多个拦截器的执行流程:

SpringBoot之HandlerInterceptorAdapter _ JavaClub全栈架构师技术笔记

如果controller出现异常,则不会继续执行postHandle,只会倒序执行afterCompletion方法

SpringBoot之HandlerInterceptorAdapter _ JavaClub全栈架构师技术笔记

SpringBoot之HandlerInterceptorAdapter _ JavaClub全栈架构师技术笔记

作者:Anlai_Wei
来源链接:https://www.cnblogs.com/weianlai/p/11358768.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/java/18427.html

标签: Spring Boot
分享给朋友:

“SpringBoot之HandlerInterceptorAdapter” 的相关文章

记一次SpringBoot项目使用RedisTemplate无法反序列化字节数组问题困扰8小时巨坑

记一次SpringBoot项目使用RedisTemplate无法反序列化字节数组问题困扰8小时巨坑

一、问题描述 问题描述: 前提:向Redis中SET值的是一个JFinal项目,使用的Jedis客户端API操作的,把一个对象转成byte[]形式存入Redis中。 然后在另一个SpringBoot项目中我通过Spring自带的RedisTempl...

SpringBoot之整合Mybatis篇

SpringBoot之整合Mybatis篇

开头语 啪嚓,醒木一拍(咳咳) ,上回书我们说到:SpringBoot的简单搭建,也就是SpringBoot的搭建流程,简单的将项目进行启动,本次,我们简单的把SpringBoot与持久层框架Mybatis进行整合,接下来,我们开始。 Mybatis名词解释   &...

SpringBoot整合SpringCloud分布式服务

SpringBoot整合SpringCloud分布式服务

一、SpringCloud是什么 度娘:Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署...

SpringBoot整合消息队列工具kafka

SpringBoot整合消息队列工具kafka

一、前言 之前整理了kafka在windows下的安装过程,也通过shell命令进行了消息产生者和消息消费者的创建及消息发送,所以想到把kafka与最流行的SpringBoot的框架进行整合,与项目结合,进行消息的发送。 二、整合开始 1.SpringBoot工程搭建,此处不多讲,可以...

SpringBoot+Mybatis框架整合Shiro权限管理

SpringBoot+Mybatis框架整合Shiro权限管理

一、前言 ​ 之前曾分享过一个关于shiro的认证原理的文章,分享了一下shiro的认证流程与shiro中的名词解释,其实shiro作为一款轻量级框架,被应用在各种中小型及大型企业的登录认证和用户授权的模块,有小伙伴称,在用SpringBoot框架,之前用过xml方式进行配置shiro框架,...

SpringBoot整合Redis缓存

SpringBoot整合Redis缓存

一、前言 之前分享过关于Redis集群如何搭建的,最近有小伙伴儿说分享一下Redis如何使用SpringBoot的整合,项目中经常使用的就是Redis,本次整合的是Redis单机版,后续会分享Redis集群版本,请多提出自己的意见。 二、开始整合 1.首先需要搭建Redis服务器,可参...

前后端分离,SpringBoot如何实现验证码操作

前后端分离,SpringBoot如何实现验证码操作

验证码的功能是防止非法用户恶意去访问登录接口而设置的一个功能,今天我们就来看看在前后端分离的项目中,SpringBoot是如何提供服务的。SpringBoot版本本文基于的Spring Boot的版本是2.6.7 。引入依赖captcha一款超简单的验证码生成,还挺好玩的.还有中文验证码,动态验证码...

SpringBoot 如何统一后端返回格式

SpringBoot 如何统一后端返回格式

在前后端分离的项目中后端返回的格式一定要友好,不然会对前端的开发人员带来很多的工作量。那么SpringBoot如何做到统一的后端返回格式呢?今天我们一起来看看。为什么要对SpringBoot返回统一的标准格式在默认情况下,SpringBoot的返回格式常见的有三种:返回String@GetMappi...

SpringBoot 如何进行参数校验

SpringBoot 如何进行参数校验

为什么需要参数校验在日常的接口开发中,为了防止非法参数对业务造成影响,经常需要对接口的参数进行校验,例如登录的时候需要校验用户名和密码是否为空,添加用户的时候校验用户邮箱地址、手机号码格式是否正确。 靠代码对接口参数一个个校验的话就太繁琐了,代码可读性极差。 Validator框架就是为了解决开发人...

Spring Boot+微信小程序

Spring Boot+微信小程序

1. 前言 微信小程序开发平台,提供有一类 API,可以让开发者获取到微信登录用户的个人数据。这类 API 统称为开放接口。 Tip:微信小程序开发平台,会把微信登录用户的个人信息分为明文数据和敏感数据。 明文数据也称为公开数据,开发者可以直接获取到,如登...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。