0


如何解决 Spring Boot 拦截器不生效的问题

在使用 Spring Boot 开发 Web 应用时,我们常常需要使用拦截器(Interceptor)来对请求进行预处理。例如,验证用户是否登录。然而,很多开发者会遇到一个常见的问题:拦截器配置了却不生效。本文将讨论一种常见的原因及其解决方案——将配置类移入正确的包下。

问题描述

我们创建了一个

  1. LoginCheckInterceptor

类,并在

  1. WebConfig

类中进行注册。但是,启动应用后发现拦截器并没有生效。

示例代码:

  1. LoginCheckInterceptor

类:

  1. package com.itheima.interceptor;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.itheima.pojo.Result;
  4. import com.itheima.utils.JwtUtils;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.springframework.stereotype.Component;
  7. import org.springframework.util.StringUtils;
  8. import org.springframework.web.servlet.HandlerInterceptor;
  9. import org.springframework.web.servlet.ModelAndView;
  10. import javax.servlet.http.HttpServletRequest;
  11. import javax.servlet.http.HttpServletResponse;
  12. @Slf4j
  13. @Component
  14. public class LoginCheckInterceptor implements HandlerInterceptor {
  15. @Override
  16. public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
  17. String url = req.getRequestURL().toString();
  18. log.info("请求的url: {}", url);
  19. if (url.contains("login")) {
  20. log.info("登录操作, 放行...");
  21. return true;
  22. }
  23. String jwt = req.getHeader("token");
  24. if (!StringUtils.hasLength(jwt)) {
  25. log.info("请求头token为空,返回未登录的信息");
  26. Result error = Result.error("NOT_LOGIN");
  27. String notLogin = JSONObject.toJSONString(error);
  28. resp.getWriter().write(notLogin);
  29. return false;
  30. }
  31. try {
  32. JwtUtils.parseJWT(jwt);
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. log.info("解析令牌失败, 返回未登录错误信息");
  36. Result error = Result.error("NOT_LOGIN");
  37. String notLogin = JSONObject.toJSONString(error);
  38. resp.getWriter().write(notLogin);
  39. return false;
  40. }
  41. log.info("令牌合法, 放行");
  42. return true;
  43. }
  44. @Override
  45. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  46. System.out.println("postHandle ...");
  47. }
  48. @Override
  49. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  50. System.out.println("afterCompletion...");
  51. }
  52. }
  1. WebConfig

类:

  1. package com.config;
  2. import com.itheima.interceptor.LoginCheckInterceptor;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  6. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  7. @Configuration
  8. public class WebConfig implements WebMvcConfigurer {
  9. @Autowired
  10. private LoginCheckInterceptor loginCheckInterceptor;
  11. @Override
  12. public void addInterceptors(InterceptorRegistry registry) {
  13. registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");
  14. }
  15. }
解决方案

  1. WebConfig

类移到

  1. itheima

包下即可解决问题。原因在于 Spring Boot 的默认包扫描机制。

原因分析

Spring Boot 使用

  1. @SpringBootApplication

注解的主应用类启动应用。该注解包含了

  1. @ComponentScan

,默认扫描主应用类所在包及其子包中的所有组件。如果

  1. WebConfig

类不在主应用类所在包或其子包下,Spring Boot 将无法自动扫描到它,从而导致拦截器不生效。

解决方法

  1. WebConfig

类移到

  1. com.itheima

包下,确保其在主应用类的扫描路径内。

调整后的目录结构:

  1. src/main/java
  2. └── com
  3. └── itheima
  4. ├── MyApplication.java
  5. ├── interceptor
  6. └── LoginCheckInterceptor.java
  7. └── config
  8. └── WebConfig.java
代码调整

  1. WebConfig

类从

  1. com.config

包移到

  1. com.itheima.config

包下:

  1. package com.itheima.config;
  2. import com.itheima.interceptor.LoginCheckInterceptor;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  6. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  7. @Configuration
  8. public class WebConfig implements WebMvcConfigurer {
  9. @Autowired
  10. private LoginCheckInterceptor loginCheckInterceptor;
  11. @Override
  12. public void addInterceptors(InterceptorRegistry registry) {
  13. registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");
  14. }
  15. }
其他解决方案

如果不想移动配置类,还可以通过以下方法显式指定扫描路径:

**1. 使用

  1. @ComponentScan

注解指定扫描包**:

  1. package com.itheima;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.context.annotation.ComponentScan;
  5. @SpringBootApplication
  6. @ComponentScan(basePackages = {"com.itheima", "com.config"})
  7. public class MyApplication {
  8. public static void main(String[] args) {
  9. SpringApplication.run(MyApplication.class, args);
  10. }
  11. }

**2. 使用

  1. @Import

注解导入配置类**:

  1. package com.itheima;
  2. import com.itheima.config.WebConfig;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. import org.springframework.context.annotation.Import;
  6. @SpringBootApplication
  7. @Import(WebConfig.class)
  8. public class MyApplication {
  9. public static void main(String[] args) {
  10. SpringApplication.run(MyApplication.class, args);
  11. }
  12. }

通过这些方式,可以确保 Spring Boot 正确扫描和加载拦截器配置类,使拦截器生效。

结论

在使用 Spring Boot 开发 Web 应用时,正确配置包扫描路径非常重要。确保配置类在主应用类的扫描路径内,可以有效解决拦截器不生效的问题。希望这篇文章能够帮助大家更好地理解 Spring Boot 的包扫描机制,并顺利解决开发中遇到的问题。

标签: spring boot 后端 java

本文转载自: https://blog.csdn.net/True_aFalse/article/details/140648032
版权归原作者 True_aFalse 所有, 如有侵权,请联系我们删除。

“如何解决 Spring Boot 拦截器不生效的问题”的评论:

还没有评论