【Java开发Spring优雅编程系列】基于WebMvcConfigurer + HandlerInterceptor 实现自定义拦截器

【Java开发Spring优雅编程系列】基于WebMvcConfigurer + HandlerInterceptor 实现自定义拦截器

一、 概述

1、拦截器是属于springmvc体系的,只能拦截controller的请求,是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行; 2、用途:在调用指定方法前后预设执行指定代码逻辑;对请求控制器功能的增强; 3、实现原理:拦截器本质是AOP切面编程的思想; 4、应用场景:拦截器可用于对用户登录态控制、日志打印、性能监测、拦截请求执行预设部分逻辑。

二、与过滤器的区别
graph LR 浏览器---过滤器---Servlet---拦截器---Controller

1、执行顺序:过滤器在前,拦截器在后; 2、配置方式:过滤器web.xml,拦截器spring的配置文件; 3、依赖环境:过滤器依赖于Servlet,拦截器依赖于Spring; 4、过滤器只对请求和响应处理,拦截器可以对SpringMvc生态下组件处理控制。 总结:过滤器用于对请求参数修改、编码转换、请求包装;拦截器可以用于执行诸如身份验证、日志记录、性能监测等任务。

三、WebMvcConfigurer介绍

在Spring MVC中,WebMvcConfigurer是一种常用的配置方式,可以允许我们自定义Spring MVC的行为,比如添加拦截器、消息转换器等;WebMvcConfigurer(推荐)和WebMvcConfigurationSupport都是Spring MVC中的组件,它们都可以用于配置Spring MVC的一些特性。 常用方法介绍:

java 复制代码
 /* 拦截器配置 */
void addInterceptors(InterceptorRegistry var1);
/* 视图跳转控制器 */
void addViewControllers(ViewControllerRegistry registry);
/**
     *静态资源处理
**/
void addResourceHandlers(ResourceHandlerRegistry registry);
/* 默认静态资源处理器 */
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
/**
     * 这里配置视图解析器
 **/
void configureViewResolvers(ViewResolverRegistry registry);
/* 配置内容裁决的一些选项*/
void configureContentNegotiation(ContentNegotiationConfigurer configurer);
/** 解决跨域问题 **/
public void addCorsMappings(CorsRegistry registry) ;
1、addInterceptors:拦截器
  • addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例;
  • addPathPatterns:用于设置拦截器的过滤路径规则;addPathPatterns("/**")对所有请求都拦截;
  • excludePathPatterns:用于设置不需要拦截的过滤规则;
java 复制代码
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**").excludePathPatterns("/emp/toLogin","/emp/login","/js/**","/css/**","/images/**");
}
2、addViewControllers:页面跳转

重写WebMvcConfigurer中的addViewControllers方法可以实现页面跳转;

java 复制代码
 @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/toLogin").setViewName("login");
    }
值的指出的是,在这里重写addViewControllers方法,并不会覆盖WebMvcAutoConfiguration(Springboot自动配置)中的addViewControllers(在此方法中,Spring Boot将"/"映射至index.html),这也就意味着自己的配置和Spring Boot的自动配置同时有效,这也是我们推荐添加自己的MVC配置的方式。
3、addResourceHandlers:静态资源

我们想自定义静态资源映射目录的话,只需重写addResourceHandlers方法即可;

java 复制代码
@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/monitorfile/**").addResourceLocations("file:D:\\");
    }
4、configureDefaultServletHandling:默认静态资源处理器
java 复制代码
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
        configurer.enable("defaultServletName");
}

此时会注册一个默认的Handler:DefaultServletHttpRequestHandler,这个Handler也是用来处理静态文件的,它会尝试映射/。当DispatcherServelt映射/时(/ 和/ 是有区别的),并且没有找到合适的Handler来处理请求时,就会交给DefaultServletHttpRequestHandler 来处理

5、configureViewResolvers:视图解析器
java 复制代码
/**
 * 配置请求视图映射
 * @return
 */
@Bean
public InternalResourceViewResolver resourceViewResolver()
{
	InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
	//请求视图文件的前缀地址
	internalResourceViewResolver.setPrefix("/WEB-INF/jsp/");
	//请求视图文件的后缀
	internalResourceViewResolver.setSuffix(".jsp");
	return internalResourceViewResolver;
}
 
/**
 * 视图配置
 * @param registry
 */
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
	super.configureViewResolvers(registry);
	registry.viewResolver(resourceViewResolver());
	/*registry.jsp("/WEB-INF/jsp/",".jsp");*/
}
6、configureContentNegotiation:配置内容裁决的一些参数
7、addCorsMappings:跨域
java 复制代码
@Override
public void addCorsMappings(CorsRegistry registry) {
    super.addCorsMappings(registry);
    registry.addMapping("/cors/**")
            .allowedHeaders("*")
            .allowedMethods("POST","GET")
            .allowedOrigins("*");
}
8、configureMessageConverters:信息转换器
java 复制代码
/**
* 消息内容转换配置
 * 配置fastJson返回json转换
 * @param converters
 */
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    //调用父类的配置
    super.configureMessageConverters(converters);
    //创建fastJson消息转换器
    FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
    //创建配置类
    FastJsonConfig fastJsonConfig = new FastJsonConfig();
    //修改配置返回内容的过滤
    fastJsonConfig.setSerializerFeatures(
            SerializerFeature.DisableCircularReferenceDetect,
            SerializerFeature.WriteMapNullValue,
            SerializerFeature.WriteNullStringAsEmpty
    );
    fastConverter.setFastJsonConfig(fastJsonConfig);
    //将fastjson添加到视图消息转换器列表内
    converters.add(fastConverter);
 
}
四、HandlerInterceptor介绍

Spring的HandlerMapping支持拦截器,拦截器必须实现HandlerInterceptor接口,此接口里面有下面3中方法:

java 复制代码
public class TestInterceptor implements HandlerInterceptor{

    public boolean preHandle(HttpServletRequest req,HttpServletResponse resp,Object handler)throws Exception{
    // 处理器执行前被调用
    return true;
    }

    publilc void postHandle(HttpServletRequest req,HttpServletResponse resp,Object handler,ModelAndView mv)throws Exception{
    // 处理器执行后被调用
    }
    public void afterCompletion(HttpServletRequest req,HttpServletResponse resp,Object handler,Exception e)throws Exception{
    //全部执行完成后调用
    }
}
1、preHandle()

处理器执行前被调用,方法返回true标识继续调用其他拦截器或者处理器,返回false表示中断流程,后续的拦截器和处理器不再执行;

2、postHandle()

处理器执行后,视图执行前调用,此时而已通过ModelAndView对象对数据模型数据进行处理或对视图进行处理;

3、afterCompletion()

整个过程结束后调用,比如性能监控中我们在这里可以记录结束时间并输出消耗的时间,也可以在这里写对资源的清理,但是只有preHandle()返回true时才会执行afterCompletion方法。

相关推荐
小小寂寞的城2 分钟前
JAVA策略模式demo【设计模式系列】
java·设计模式·策略模式
志辉AI编程17 分钟前
别人还在入门,你已经精通!Claude Code进阶必备14招
后端·ai编程
JAVA学习通20 分钟前
图书管理系统(完结版)
java·开发语言
代码老y24 分钟前
Spring Boot项目中大文件上传的高级实践与性能优化
spring boot·后端·性能优化
abigalexy26 分钟前
深入Java锁机制
java
paishishaba27 分钟前
处理Web请求路径参数
java·开发语言·后端
神仙别闹29 分钟前
基于Java+MySQL实现(Web)可扩展的程序在线评测系统
java·前端·mysql
程序无bug30 分钟前
Java中的8中基本数据类型转换
java·后端
雨落倾城夏未凉34 分钟前
8.Qt文件操作
c++·后端·qt
51738 分钟前
Django中序列化与反序列化
后端·python·django