Loading... # 背景 场景是我在拦截器中加入一个鉴权的模块,有些地址某些用户是可以访问的,有些地址某些用户是不可以访问的,我们的拦截器是通过MVC配置中添加的,而配置我们用的是`@Configuration`进行标识的,而工具类(Bean)是通过`@Component`进行标识的。 # 故障 注入的工具类空指针 ```bash Caused by: java.lang.NullPointerException: Cannot invoke "top.zunmx.demo.configure.utils.PermissionUtils.can_access(String)" because "this.permissionUtils" is null at top.zunmx.demo.configure.Interceptor.preHandle(Interceptor.java:23) ~[classes/:na] at org.springframework.web.servlet.HandlerExecutionChain.applyPreHandle(HandlerExecutionChain.java:146) ~[spring-webmvc-6.1.2.jar:6.1.2] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1084) ~[spring-webmvc-6.1.2.jar:6.1.2] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.2.jar:6.1.2] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.2.jar:6.1.2] ... 36 common frames omitted ``` # 相关代码 ## 拦截器 ```java package top.zunmx.demo.configure; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.HandlerInterceptor; import top.zunmx.demo.utils.PermissionUtils; import java.util.logging.Level; import java.util.logging.Logger; public class Interceptor implements HandlerInterceptor { @Autowired private PermissionUtils permissionUtils; Logger logger = Logger.getLogger("Interceptor"); public Interceptor() { logger.log(Level.INFO, "拦截器创建" + this); } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { logger.log(Level.INFO, "当前访问:" + request.getMethod() + "-->" + request.getRequestURI()); boolean b = permissionUtils.can_access(request.getRequestURI()); if(b){ response.getWriter().print( request.getMethod() + "-->" + request.getRequestURI()); return false; // 为了屏蔽error页(DEMO) }else{ response.getWriter().print("ACCESS DENIED"); return false; } } } ``` ## MVC配置 ```java package top.zunmx.demo.configure; 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 WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new Interceptor()); } } ``` ## 鉴权工具类 ```java package top.zunmx.demo.utils; import org.springframework.stereotype.Component; import java.util.logging.Level; import java.util.logging.Logger; @Component public class PermissionUtils { Logger logger = Logger.getLogger("Interceptor"); public PermissionUtils() { logger.log(Level.INFO, "授权工具类创建" + this); } /** * 是否可以访问? * * @param path * @return */ public boolean can_access(String path) { return !path.equals("/admin"); } /** * 设置权限 * * @param path * @param ok * @return */ public boolean set_permission(String path, boolean ok) { return true; } } ``` # 解决方案 1. 去掉鉴权工具类的`@Component`注解 2. 在`WebMvcConfig`修改为以下代码 > ``` > @Bean > public PermissionUtils getPermissionUtils(){ > return new PermissionUtils(); > } > > @Override > public void addInterceptors(InterceptorRegistry registry) { > registry.addInterceptor(new Interceptor(getPermissionUtils())); > } > ``` 3. 拦截器去掉`@Autowired`,以构造方法形式注入(终于明白为什么`@Autowired`会有黄色波浪线了) > ``` > private PermissionUtils permissionUtils; > Logger logger = Logger.getLogger("Interceptor"); > > public Interceptor(PermissionUtils permissionUtils) { > this.permissionUtils = permissionUtils; > logger.log(Level.INFO, "拦截器创建" + this); > } > ``` ![demo](https://www.zunmx.top/usr/uploads/2024/01/4102346943.png) ![image.png](https://www.zunmx.top/usr/uploads/2024/01/3676406887.png) # 注意 一定要取消掉鉴权工具类的`@Component`注解,否则可能会创建多个对象 如果不去掉的话,会是这个样子的。 ![image.png](https://www.zunmx.top/usr/uploads/2024/01/2366176684.png) # 示例下载 [src.zip](https://www.zunmx.top/usr/uploads/2024/01/3259661285.zip) © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏