目录
- 问题描述
- 解决方案
- 原因分析
- 解决方法
- 代码调整
- 其他解决方案
- 结论
在使用 Spring Boot 开发 Web 应用时,我们常常需要使用拦截器(Interceptor)来对请求进行预处理。例如,验证用户是否登录。然而,很多开发者会遇到一个常见的问题:拦截器配置了却不生效。本文将讨论一种常见的原因及其解决方案——将配置类移入正确的包下。
问题描述
我们创建了一个 LoginCheckInterceptor 类,并在 WebConfig 类中进行注册。但是,启动应用后发现拦截器并没有生效。
示例代码:
LoginCheckInterceptor 类:
pa编程ckage com.itheima.interceptor;
import com.alibaba.fastjson.JSONObject;
import com.itheima.pojo.Result;
import com.itheima.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.swww.devze.comtereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import Javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
@Compjsonent
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
String url = req.getRequestURL().toString();
php log.info("请求的url: {}", url);
if (url.contains("login")) {
log.info("登录操作, 放行...");
return true;
}
String jwt = req.getHeader("token");
if (!StringUtils.hasLength(jwt)) {
log.info("请求头token为空,返回未登录的信息");
Result error = Result.error("NOT_LOGIN");
String notLogin = JSONObject.toJSONString(error);
resp.getWriter().write(notLogin);
return false;
}
try {
JwtUtils.parseJWT(jwt);
} catch (Exception e) {
e.printStackTrace();
log.info("解析令牌失败, 返回未登录错误信息");
Result error = Result.error("NOT_LOGIN");
String notLogin = JSONObject.toJSONString(error);
resp.getWriter().write(notLogin);
return false;
}
log.info("令牌合法, 放行");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle ...");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion...");
}
}
WebConfig 类:
package com.config;
import com.itheima.interceptor.LoginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotatioandroidn.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginCheckInterceptor loginCheckInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");
}
}
解决方案
将 WebConfig 类移到 itheima 包下即可解决问题。原因在于 Spring Boot 的默认包扫描机制。
原因分析
Spring Boot 使用 @SpringBootApplication 注解的主应用类启动应用。该注解包含了 @ComponentScan,默认扫描主应用类所在包及其子包中的所有组件。如果 WebConfig 类不在主应用类所在包或其子包下,Spring Boot 将无法自动扫描到它,从而导致拦截器不生效。
解决方法
将 WebConfig 类移到 com.itheima 包下,确保其在主应用类的扫描路径内。
调整后的目录结构:
src/main/java
└── com
└── itheima
├── MyApplication.java
├── interceptor
│ └── LoginCheckInterceptor.java
└── config
└── WebConfig.java
代码调整
将 WebConfig 类从 com.config 包移到 com.itheima.config 包下:
package com.itheima.config;
import com.itheima.interceptor.LoginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
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 {
@Autowired
private LoginCheckInterceptor loginCheckInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");
}
}
其他解决方案
如果不想移动配置类,还可以通过以下方法显式指定扫描路径:
1. 使用 @ComponentScan 注解指定扫描包:
package com.itheima;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = {"com.itheima", "com.config"})
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
2. 使用 @Import 注解导入配置类:
package com.itheima;
import com.itheima.config.WebConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
@SpringBootApplication
@Import(WebConfig.class)
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
通过这些方式,可以确保 Spring Boot 正确扫描和加载拦截器配置类,使拦截器生效。
结论
在使用 Spring Boot 开发 Web 应用时,正确配置包扫描路径非常重要。确保配置类在主应用类的扫描路径内,可以有效解决拦截器不生效的问题。希望这篇文章能够帮助大家更好地理解 Spring Boot 的包扫描机制,并顺利解决开发中遇到的问题。
到此这篇关于SpringBoot拦截器不生效的问题解决的文章就介绍到这了,更多相关SpringBoot拦截器不生效内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
加载中,请稍侯......
精彩评论