目录
- 问题描述
- 解决方案
- 原因分析
- 解决方法
- 代码调整
- 其他解决方案
- 结论
在使用 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)!
精彩评论