SpringBoot添加拦截器不生效
解决拦截器不生效的问题
我想要实现,每次访问登录之后才能的url时,需要验证此时是否为登录状态,这里是通过判断session中是否还存在用户信息,因为登录时会存储用户信息,在退出时会清除用户的信息。所以想要通过拦截器来实现。
-
首先需要自定义拦截器,具体代码如下:
package com.dk.common.intercepter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 定义拦截器 * @author MJH on 2021/6/1. * @version 1.0 */ @Component //@Component标签相当于配置文件中的<bean id="" class=""/>,以后可以直接放入到@Configuration标注的类中 public class SimpleIntercepter implements HandlerInterceptor { //获取日志 private Logger logger = LoggerFactory.getLogger(this.getClass()); /* * 进入controller层之前拦截请求 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //不是含有"/admin"的链接不进行拦截 if(!request.getRequestURI().contains("/admin")){ return true; } //查看session里面是否有"name"的数据 String username = null; if((username = (String) request.getSession().getAttribute("USERNAME"))!=null){ logger.info("user:"+username+"发送了请求"); return true; } return false; } /* * 处理请求完成后视图渲染之前的处理操作 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { logger.info("postHandle.................."); } /* * 视图渲染之后的操作 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { logger.info("请求响应完成"); } }
-
需要SpringBoot注册拦截器,具体代码如下:
package com.dk.config; import com.dk.common.intercepter.SimpleIntercepter; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import javax.annotation.Resource; /** * springboot注册拦截器 * @author MJH on 2021/6/1. * @version 1.0 */ @Configuration //SimpleIntercepter相当于一个Bean,因为它被@Component标注过 public class UserInterceptorAppConfig implements WebMvcConfigurer { @Resource SimpleIntercepter simpleIntercepter; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(simpleIntercepter).addPathPatterns("/admin/*"); } }
以上代码是参考博客springboot(六):springboot使用过滤器、拦截器,注意在自定义拦截器上加上注解@Component
,在注册拦截器时加上注解@Configuration
但我设置好后,启动项目拦截器并没有生效,查阅资料了解到是因为同时有多个配置类都实现了WebMvcConfigurer
或继承了WebMvcConfigurationSupport
,导致后只会有一个生效,解决办法是,将这些配置都在一个类中设置,即将代码整合至一个类中,此处我是除了拦截器这里,还有跨域配置和上传文件配置,于是将他们整合至一个类中,代码如下:
package com.dk.config;
import com.dk.common.intercepter.SimpleIntercepter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.*;
import java.util.Collections;
/**
* 解决跨域问题
* @author MJH on 2021/3/29.
* @version 1.0
*
*/
@Configuration
public class CorsConfig extends WebMvcConfigurationSupport {
@Autowired
private SimpleIntercepter simpleIntercepter;
//解决跨域问题
@Override
protected void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowCredentials(true)
.allowedMethods("*").maxAge(3600);
}
//将自定义的拦截器注册
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(simpleIntercepter).addPathPatterns("/admin/**");
}
/**
* 图片保存路径,自动从yml文件中获取数据
* 示例: D:/images/
*/
@Value("${file-save-path}")
private String fileSavePath;
//设置文件保存路径
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
/**
* 配置资源映射
* 意思是:如果访问的资源路径是以“/images/”开头的,
* 就给我映射到本机的“E:/images/”这个文件夹内,去找你要的资源
* 注意:E:/images/ 后面的 “/”一定要带上
*/
registry.addResourceHandler("/images/**")
.addResourceLocations("file:"+fileSavePath);
}
}
将相关配置整合在一起后,启动项目,拦截器仍然没有生效,后来查阅资料了解是WebMvcConfigurationSupport
和WebMvcConfigurer
的区别导致的,我将extends WebMvcConfigurationSupport
改为implements WebMvcConfigurer
后,拦截器生效了,那看来我的问题确实是这里导致的,改后代码为:
package com.dk.config;
import com.dk.common.intercepter.SimpleIntercepter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.*;
import java.util.Collections;
/**
* 解决跨域问题
* @author MJH on 2021/3/29.
* @version 1.0
*
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer { //此处写extends WebMvcConfigurationSupport拦截器没生效,改为这个生效了
@Autowired
private SimpleIntercepter simpleIntercepter;
//解决跨域问题
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowCredentials(true)
.allowedMethods("*").maxAge(3600);
}
//将自定义的拦截器注册
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(simpleIntercepter).addPathPatterns("/admin/**");
}
/**
* 图片保存路径,自动从yml文件中获取数据
* 示例: D:/images/
*/
@Value("${file-save-path}")
private String fileSavePath;
//设置文件保存路径
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/**
* 配置资源映射
* 意思是:如果访问的资源路径是以“/images/”开头的,
* 就给我映射到本机的“E:/images/”这个文件夹内,去找你要的资源
* 注意:E:/images/ 后面的 “/”一定要带上
*/
registry.addResourceHandler("/images/**")
.addResourceLocations("file:"+fileSavePath);
}
}
此处的解决方案我是参考博客Spring Boot 拦截器无效,不起作用,该篇博客评论区中还有很多其他原因导致的,可以参考。