服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - SpringBoot自定义拦截器interceptor使用详解

SpringBoot自定义拦截器interceptor使用详解

2023-10-19 15:09mao_mao37 Java教程

Intercepter是由Spring提供的Intercepter拦截器,主要应用在日志记录、权限校验等安全管理方便。

Spring Boot拦截器Intercepter详解

Intercepter是由Spring提供的Intercepter拦截器,主要应用在日志记录、权限校验等安全管理方便。

使用过程

1.创建自定义拦截器,实现HandlerInterceptor接口,并按照要求重写指定方法

HandlerInterceptor接口源码:

public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}

根据源码可看出HandlerInterceptor接口提供了三个default方法,这三个方法作用不同,用户想要自定义个一个指定拦截规则的拦截器,需要重写其中一个或者多个方法,这三个方法作用如下:

  • perHandle:preHandle方法的作用是,当请求在进入controller之前拦截请求,对请求进行预处理,比如登录验证(cookie,token,referer)或者单点登录cookie解析都可以在这方法中进行。该方法的返回值,如果返回true,表示放行至controller业务层,如果false,表示请求非法,结束请求并返回错误信息。
  • postHandler:postHandle方法是在请求被controller处理完但是还未传递到业务模板进行渲染拦截,即controller处理完,返回ModelAndView 之前执行该方法,可以操控ModelAndView的值;所以该方法多了一个参数,ModelAndView,这个参数包含了controller处理完后需要传递的Model参数,因此,我们可以在该方法通过ModelAndView对象对返给前端的额视图做一定的修改。
  • afterCompletion:afterCompletion方法作用就是做些收尾工作,在ModelAndView返回前端进行渲染后执行,比如有时候我们需要把每个线程的局部变量(如User信息)放入到TheradLocal中,为了防止内存泄露,在最后需要清除ThreadLocal的内容,此操作就可以放在该方法中执行。

自定义一个获取并返回某个静态资源的内容已整个请求所花费时间的时间拦截器

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class MyInterceptor implements HandlerInterceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyInterceptor.class);

    private static final ThreadLocal START_THREAD_LOCAL = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        String uri = request.getRequestURI();
        LOGGER.info(uri + " preHandle");
        Long startTime = System.currentTimeMillis();    //获取开始时间
        START_THREAD_LOCAL.set(startTime);  //线程绑定变量(该数据只有当前请求的线程可见)
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        String uri = request.getRequestURI();
        LOGGER.info(uri + " postHandle");
        Long startTime = START_THREAD_LOCAL.get();//得到线程绑定的局部变量(开始时间)
        Long endTime = System.currentTimeMillis(); 	//2、结束时间
        Long time = endTime - startTime;
        LOGGER.info("http request all time: " + time + "ms");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                Exception ex) throws Exception {
        String uri = request.getRequestURI();
        LOGGER.info(uri + " afterCompletion");
        if (START_THREAD_LOCAL != null) {
            START_THREAD_LOCAL.remove();    // 移除ThreadLocal中的局部变量
        }
    }
}
2.添加配置类,实现WebMvcController接口,并添加@Configuration注解,在配置类中,重写addIntercepters方法,添加要拦截的url以及url白名单(需要排除拦截的url)

WebMvcConfigurer源码:

public interface WebMvcConfigurer {

	default void configurePathMatch(PathMatchConfigurer configurer) {
	}

	default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
	}

	default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
	}

	default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
	}

	default void addFormatters(FormatterRegistry registry) {
	}

	default void addInterceptors(InterceptorRegistry registry) {
	}

	default void addResourceHandlers(ResourceHandlerRegistry registry) {
	}

	default void addCorsMappings(CorsRegistry registry) {
	}

	default void addViewControllers(ViewControllerRegistry registry) {
	}

	default void configureViewResolvers(ViewResolverRegistry registry) {
	}

	default void addArgumentResolvers(List resolvers) {
	}

	default void addReturnValueHandlers(List handlers) {
	}

	default void configureMessageConverters(List> converters) {
	}

	default void extendMessageConverters(List> converters) {
	}

	default void configureHandlerExceptionResolvers(List resolvers) {
	}

	default void extendHandlerExceptionResolvers(List resolvers) {
	}

	@Nullable
	default Validator getValidator() {
		return null;
	}

	@Nullable
	default MessageCodesResolver getMessageCodesResolver() {
		return null;
	}
}

根据源码可以看出,WebMvcConfigurer提供了多个方法,并且也都是default方法,也是根据我们自定义配置,重写其中一个或者多个方法,这里就介绍两个常用的方法:

  • addInterceptors:从该方法名就可以了解到该方法是添加拦截器,即将拦截器交给IOC去执行,拦截器需要拦截的路径以及需要排除拦截的路径在该方法中配置。
  • addResourceHandlers:该方法的作用是配置静态资源路径。即某些请求需要读取某个路径下的静态资源内容,需要配置该静态资源的路径,通过该方法可以统一给这些请求配置指定静态资源路径 。

实例:

import com.eureka.intercrpotor.MyInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Bean
    public MyInterceptor myInterceptor() {
        return new MyInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor())  // 添加拦截器
                .addPathPatterns("/**")          // 配置拦截请求url( ** 表示拦截所有请求url)
                .excludePathPatterns("/hello"); // 排除某些不需要拦截的请求url(即带有/hello请求不会被拦截)
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")   // 配置需要添加静态资源的请求url
                .addResourceLocations("classpath:/mydata/");   //配置静态资源路径
    }
}

测试:

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    
    @GetMapping("/test/interceptor")
    public ResponseEntity testInterceptor() {
        return ResponseEntity.ok("successful");
    }
}

静态资源:

SpringBoot自定义拦截器interceptor使用详解

 启动项目后访问 localhost:60011/test/interceptor:

SpringBoot自定义拦截器interceptor使用详解

 控制台打印的日志:

SpringBoot自定义拦截器interceptor使用详解

 我们再通过url访问静态资源请求 localhost:60011/test.jpg

SpringBoot自定义拦截器interceptor使用详解

到此这篇文章就介绍到这了,更多相关内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文地址:https://blog.csdn.net/mao_mao37/article/details/132225241

延伸 · 阅读

精彩推荐
  • Java教程Spring的BeanFactoryPostProcessor接口示例代码详解

    Spring的BeanFactoryPostProcessor接口示例代码详解

    这篇文章主要介绍了Spring的BeanFactoryPostProcessor接口,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    程序员自由之路8592021-08-13
  • Java教程Java常用开源库汇总

    Java常用开源库汇总

    这篇文章主要介绍了Java常用开源库的相关资料,文中讲解非常细致,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下 ...

    请叫我头头哥5072020-07-20
  • Java教程elasticsearch启动警告无法锁定JVM内存

    elasticsearch启动警告无法锁定JVM内存

    今天小编就为大家分享一篇关于elasticsearch启动警告无法锁定JVM内存,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随...

    Scub9912019-06-21
  • Java教程springboot集成RestTemplate及常见的用法说明

    springboot集成RestTemplate及常见的用法说明

    这篇文章主要介绍了springboot集成RestTemplate及常见的用法说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...

    重度孤独症患者4232022-03-06
  • Java教程Java模拟实现斗地主发牌

    Java模拟实现斗地主发牌

    这篇文章主要为大家详细介绍了Java实现模拟斗地主发牌,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    菜鸟的第一天10772021-10-27
  • Java教程IDEA下使用MyBatisCodeHelper插件的方法详解

    IDEA下使用MyBatisCodeHelper插件的方法详解

    这篇文章主要介绍了IDEA下使用MyBatisCodeHelper插件的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    大道之简5832020-09-29
  • Java教程Java文件字符输入流FileReader读取txt文件乱码的解决

    Java文件字符输入流FileReader读取txt文件乱码的解决

    这篇文章主要介绍了Java文件字符输入流FileReader读取txt文件乱码的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,...

    春天里的小矮宝5192021-12-18
  • Java教程Java多线程中Lock锁的使用总结

    Java多线程中Lock锁的使用总结

    这篇文章主要介绍了Java多线程中Lock锁的使用总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下...

    fancyerII4672020-08-04