前言

之前在【快学springboot】6.WebMvcConfigurer配置静态资源和解决跨域里有用到WebMvcConfigurer接口来实现静态资源的映射和解决跨域请求,并且在文末还说了WebMvcConfigurer(springboot2.x之后使用该接口,springboot1.x使用WebMvcConfigurerAdapter类,不过该类已经被标识过期了)可以配置很多东西,如下:

下面,我们就通过代码,使用WebMvcConfigurer接口来实现一个springboot的拦截器。

WebMvcConfigurer的addInterceptors方法添加拦截器

这里都是基于之前的项目开发的,之前的WebConfig.java如下:

@Configuration
public class WebConfig implements WebMvcConfigurer {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/file/**")
.addResourceLocations("file:D:\");
}

/**
* 跨域支持
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH")
.maxAge(3600 * 24);
}

}

之前已经实现了静态资源和解决跨域问题的配置。我们可以重写WebMvcConfigurer的addInterceptors方法来实现拦截器:

@Override
public void addInterceptors(InterceptorRegistry registry) {

}

我们只需要通过registry.addInterceptor( )添加一个拦截器即可

实现拦截器

新建一个RequestInterceptor.java,实现HandlerInterceptor接口,如下:

@Component
public class RequestInterceptor implements HandlerInterceptor {


}

这里别忘了加上Component注解。

我们可以通过接口的方法列表查看下,我们可以实现那些功能:

可以看到,我们可以实现preHandle、postHandle和afterCompletion这三个方法。

preHandle

preHandle 方法,通过字面意思不难理解,此方法会在处理每个请求之前先执行。此方法的返回一个布尔值,如果返回为false ,表示请求结束。我们重写该方法,直接返回一个false:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("请求进来了");
return false;
}

并且把该拦截器在WebConfig中进行注册:

这时候启动项目,拦截器已经可以起作用了,不过这时候访问会没有返回,我们可以通过response来返回一些信息,如下:

这时候,直接访问项目根路径:

查看控制台

如果有全局异常捕获的话,我们还可以通过抛出异常的形式来返回值。

postHandle

这个方法是处理请求之后,但是在返回数据之前执行的。我们可以通过这样一个方法(这个方法是之前文章里有的啦)来验证,在return处打一个端点:

@PostMapping
public Object addUser() {
Map<String, String> map = new HashMap<>();
map.put("name", "happyjava");
return "OK";
}

实现postHandle方法,如下:

运行程序,请求接口:

在断点处停了下来,但是并没有看到控制台输出了“执行了postHandle”。

afterCompletion

顾名思义,这个方法实在处理完成并且返回结果之后执行的。这个方法更多是用来关闭一些资源的吧,比如ThreadLocal,日志MDC之类的。实现afterCompletion方法如下:

我们在sout出打一个断点,然后发起接口请求。效果如下:

线程在断点处停止了,但是请求已经拿到了数据。不过需要注意的是,如果在处理请求出现异常的时候,该方法还是会在返回数据之前执行的(Exception参数就是给我们处理异常用的),并且你可以拿到执行时所抛出的异常信息(没有配置异常拦截器的话,如果配置饿了异常拦截器,ex会为null,所以我们需要先把全局异常拦截器去掉)。修改controller方法如下:

@PostMapping
public Object addUser() {
// 新增一个用户
Map<String, String> map = new HashMap<>();
map.put("name", "happyjava");
throw new RuntimeException();
// return "OK";
}

使他抛出一个异常。然后执行请求:

只是后,postman还在等待数据,并且程序执行到了断点处。并且可以看到,ex就是我们手动抛出的异常。

把断点放掉,postman成功拿到了数据。其实我们也可以通过这个来做一个全局异常处理器,不过完全没有这个必要性。

【快学springboot】12.实现拦截器的更多相关文章

  1. 【快学springboot】4.接口参数校验

    前言 在开发接口的时候,参数校验是必不可少的.参数的类型,长度等规则,在开发初期都应该由产品经理或者技术负责人等来约定.如果不对入参做校验,很有可能会因为一些不合法的参数而导致系统出现异常. 上一篇文 ...

  2. 【快学SpringBoot】Spring Cache+Redis实现高可用缓存解决方案

    前言 之前已经写过一篇文章介绍SpringBoot整合Spring Cache,SpringBoot默认使用的是ConcurrentMapCacheManager,在实际项目中,我们需要一个高可用的. ...

  3. SpringBoot如何添加拦截器

    在web开发的过程中,为了实现登录权限验证,我们往往需要添加一个拦截器在用户的的请求到达controller层的时候实现登录验证,那么SpringBoot如何添加拦截器呢? 步骤如下: 1.继承Web ...

  4. 在springboot中使用拦截器

    在springMVC中可以实现拦截器,是通过实现HandlerInterceptor接口,然后在springmvc-web.xml中配置就可以使用拦截器了.在springboot中拦截器也是一样的思想 ...

  5. Springboot + redis + 注解 + 拦截器来实现接口幂等性校验

    Springboot + redis + 注解 + 拦截器来实现接口幂等性校验   1. SpringBoot 整合篇 2. 手写一套迷你版HTTP服务器 3. 记住:永远不要在MySQL中使用UTF ...

  6. 【快学springboot】13.操作redis之String数据结构

    前言 在之前的文章中,讲解了使用redis解决集群环境session共享的问题[快学springboot]11.整合redis实现session共享,这里已经引入了redis相关的依赖,并且通过spr ...

  7. 【快学springboot】8.JPA乐观锁OptimisticLocking

    介绍 当涉及到企业应用程序时,正确地管理对数据库的并发访问是至关重要的.为此,我们可以使用Java Persistence API提供的乐观锁定机制.它导致在同一时间对同一数据进行多次更新不会相互干扰 ...

  8. springmvc以及springboot中的拦截器配置

    拦截器两种实现   如果不同的controller中都需要拦截器,不能使用相同的拦截器,因为拦截器不能跨controller,这个时候只能为不同的controller配置不同的拦截器,每一个拦截器只能 ...

  9. springboot中使用拦截器、监听器、过滤器

     拦截器.过滤器.监听器在web项目中很常见,这里对springboot中怎么去使用做一个总结. 1. 拦截器(Interceptor)   我们需要对一个类实现HandlerInterceptor接 ...

随机推荐

  1. C语言:将3*4矩阵中找出行最大,列最小的那个元素。-将低于平均值的人数作为函数返回值,将低于平均分的分数放入below数组中。

    //将3*4矩阵中找出行最大,列最小的那个元素. #include <stdio.h> #define M 3 #define N 4 void fun(int (*a)[N]) { ,j ...

  2. rapidxml编写xml文件(er)

    一.以rapidxml::node_declaration形式写xml文件第一行 int write(void) { ; rapidxml::xml_document<> doc; rap ...

  3. Java面向对象简单知识总结-考试用

    类.对象.构造器 类定义了属性.方法,是抽象的,写在扩展名为java的文件中. 对象是类的实体,是具体的. 构造器:方法名与类名一致.没有返回类型,可以重载不能重写.在创建对象时调用.使用new调用实 ...

  4. PAT 1003 Emergency (25分)

    As an emergency rescue team leader of a city, you are given a special map of your country. The map s ...

  5. 利用graphviz软件和pycallgraph库自动生成Python代码函数调用关系图

    参考博文:https://blog.csdn.net/qq_36408085/article/details/82952846 https://blog.csdn.net/fondax/article ...

  6. Hibernate学习(五)

    自关联测试案例 1.创建表 drop table if exists t_category ; create table t_category ( id ) primary key , name ) ...

  7. Wireless-MCS

    MCS是modulation and coding scheme的缩写,可以翻译为调制和编码格式,我们可以选择配置该参数,来选择AP和Client之间传输的MCS rate,这些数据速率是使用shor ...

  8. javascript 原型继承 与class extends 继承对比

      //父类 Animal function Animal (name) { this.name = name; this.sleep = function () { console.log(this ...

  9. 洛谷P1164小A点菜(01背包)

    题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:“随便点”. 题目描述 不过uim由于买了一些辅(e ...

  10. Myeclipse下PHP开发环境搭建及运行

    外接CSDN链接 http://blog.csdn.net/yuxiangaaaaa/article/details/54948426 这是php初始设置,后面进行重新设置