springboot拦截器注入service,spring排除bean注入
目录
简介问题重现解决方案
简介
说明
本文用示例介绍如何解决拦截器中注入豆失败的问题。
场景
代币拦截器中需要用@自动连线注入JavaJwtUtil类,结果发现注入的JavaJwtUtil为零.
原因
拦截器的配置类是以新JwtInterceptor的方式使用的,那么这个JwtInterceptor不受弹簧管理。因此,里边@自动连线注入JavaJwtUtil是不会注入进去的。
问题重现
代码
应用程序.阳明海运股份有限公司
服务器:端口: 8080春天:应用程序:名称:弹簧靴-jwtconfig : jwt : #密钥secret: abcd1234 #令牌过期时间(5分钟)。单位:毫秒.到期: 300000
拦截器配置
@配置公共类拦截器配置实现WebMvcConfigurer { @ Override public void add interceptors(InterceptorRegistry){ registry。添加拦截器(新的jwt拦截器());}}拦截器
包com。举例。演示。截击机;导入com。举例。演示。util。javajwtutil导入龙目岛。外部人员。SLF 4j。SLF 4j;导入org。spring框架。豆子。beans异常;导入org。spring框架。豆子。工厂。注释。自动连线;导入org。spring框架。语境。应用程序上下文;导入组织。spring框架。语境。applicationcontextaware导入org。spring框架。刻板印象。组件;导入org。spring框架。util。字符串实用程序;导入org。spring框架。网络。方法。处理程序方法;导入org。spring框架。网络。servlet。处理者受体;导入javax。注释。后期构造;导入javax。servlet。http。http servlet请求;导入javax。servlet。http。http servlet响应;导入Java。util。数组;导入Java。util。列表;@Slf4j@Componentpublic类JwtInterceptor实现处理程序拦截器{ @ auto wired JavaJwtUtil JavaJwtUtil;ListString白名单=数组。aslist(/auth/log in ,/error );@ Override public boolean preHandle(http servlet请求请求、HttpServletResponse响应、对象处理程序)引发异常{ //如果不是映射到方法直接通过如果(!(HandlerMethod方法的处理程序实例)){返回true} //放过不需要验证的页面字符串uri=请求。get request uri();if (whiteList.contains(uri)) {返回true} //头部和参数都查看一下是否有令牌字符串令牌=请求。get头( token );
if (StringUtils.isEmpty(token)) { token = request.getParameter("token"); if (StringUtils.isEmpty(token)) { throw new RuntimeException("token是空的"); } } if (!javaJwtUtil.verifyToken(token)) { log.error("token无效"); return false; } String userId = javaJwtUtil.getUserIdByToken(token); log.info("userId:" + userId); String userName = javaJwtUtil.getUserNameByToken(token); log.info("userName:" + userName); return true; }}Jwt工具类
package com.example.demo.util;import com.auth0.jwt.JWT;import com.auth0.jwt.JWTVerifier;import com.auth0.jwt.algorithms.Algorithm;import com.auth0.jwt.exceptions.JWTDecodeException;import com.auth0.jwt.exceptions.JWTVerificationException;import com.auth0.jwt.interfaces.DecodedJWT;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;import java.util.Date;@Componentpublic class JavaJwtUtil { //过期时间 @Value("${config.jwt.expire}") private Long EXPIRE_TIME; //密钥 @Value("${config.jwt.secret}") private String SECRET; // 生成Token,五分钟后过期 public String createToken(String userId) { try { Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME); Algorithm algorithm = Algorithm.HMAC256(SECRET); return JWT.create() // 将 user id 保存到 token 里面 .withAudience(userId) // date之后,token过期 .withExpiresAt(date) // token 的密钥 .sign(algorithm); } catch (Exception e) { return null; } } // 根据token获取userId public String getUserIdByToken(String token) { try { String userId = JWT.decode(token).getAudience().get(0); return userId; } catch (JWTDecodeException e) { return null; } } // 根据token获取userName public String getUserNameByToken(String token) { try { String userName = JWT.decode(token).getSubject(); return userName; } catch (JWTDecodeException e) { return null; } } //校验token public boolean verifyToken(String token) { try { Algorithm algorithm = Algorithm.HMAC256(SECRET); JWTVerifier verifier = JWT.require(algorithm) // .withIssuer("auth0") // .withClaim("username", username) .build(); DecodedJWT jwt = verifier.verify(token); return true; } catch (JWTVerificationException exception) {// throw new RuntimeException("token 无效,请重新获取"); return false; } }}
Controller
package com.example.demo.controller;import com.example.demo.util.JavaJwtUtil;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/auth")public class AuthController { @Autowired JavaJwtUtil javaJwtUtil; @RequestMapping("/login") public String login() { // 验证userName,password和数据库中是否一致,如不一致,直接返回失败 // 通过userName,password从数据库中获取userId String userId = 5 + ""; String token = javaJwtUtil.createToken(userId); System.out.println("token:" + token); return token; } //需要token验证 @RequestMapping("/info") public String info() { return "验证通过"; }}
测试
访问:http://localhost:8080/auth/login
前端结果:一串token字符串
访问:http://localhost:8080/auth/info(以token作为header或者参数)
后端结果
java.lang.NullPointerException: nullat com.example.demo.interceptor.JwtInterceptor.preHandle(JwtInterceptor.java:55) ~[main/:na]
解决方案
方案简述
配置类中将new JwtInterceptor()改为Bean的方式
配置类
package com.example.demo.interceptor;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configurationpublic class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(getJwtInterceptor()); } @Bean JwtInterceptor getJwtInterceptor() { return new JwtInterceptor(); }}
拦截器(此时无需@Component)
package com.example.demo.interceptor;import com.example.demo.util.JavaJwtUtil;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.util.StringUtils;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.Arrays;import java.util.List;@Slf4jpublic class JwtInterceptor implements HandlerInterceptor { @Autowired JavaJwtUtil javaJwtUtil; List<String> whiteList = Arrays.asList( "/auth/login", "/error" ); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 如果不是映射到方法直接通过 if (!(handler instanceof HandlerMethod)) { return true; } //放过不需要验证的页面。 String uri = request.getRequestURI(); if (whiteList.contains(uri)) { return true; } // 头部和参数都查看一下是否有token String token = request.getHeader("token"); if (StringUtils.isEmpty(token)) { token = request.getParameter("token"); if (StringUtils.isEmpty(token)) { throw new RuntimeException("token是空的"); } } if (!javaJwtUtil.verifyToken(token)) { log.error("token无效"); return false; } String userId = javaJwtUtil.getUserIdByToken(token); log.info("userId:" + userId); String userName = javaJwtUtil.getUserNameByToken(token); log.info("userName:" + userName); return true; }}
到此这篇关于Spring拦截器中注入Bean失败解放方案详解的文章就介绍到这了,更多相关SpringBean内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。