最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring攔截器中注入Bean失敗解放方案詳解

 更新時間:2022年06月21日 08:34:39   作者:IT利刃出鞘  
這兩天遇到SpringBoot攔截器中Bean無法注入問題。下面介紹關(guān)于SpringBoot攔截器中Bean無法注入的問題解決方案,感興趣的朋友一起看看吧

簡介

說明

本文用示例介紹如何解決攔截器中注入Bean失敗的問題。

場景

Token攔截器中需要用@Autowired注入JavaJwtUtil類,結(jié)果發(fā)現(xiàn)注入的JavaJwtUtil為Null。

原因

攔截器的配置類是以new JwtInterceptor的方式使用的,那么這個JwtInterceptor不受Spring管理。因此,里邊@Autowired注入JavaJwtUtil是不會注入進去的。

問題重現(xiàn)

代碼

application.yml

server:
  port: 8080
spring:
  application:
    name: springboot-jwt
config:
  jwt:
    # 密鑰
    secret: abcd1234
    # token過期時間(5分鐘)。單位:毫秒.
    expire: 300000

攔截器配置

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JwtInterceptor());
    }
}

攔截器

package com.example.demo.interceptor;
import com.example.demo.util.JavaJwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
@Slf4j
@Component
public 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;
        }
        // 頭部和參數(shù)都查看一下是否有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;
    }
}

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;
@Component
public 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;
        }
    }
    // 根據(jù)token獲取userId
    public String getUserIdByToken(String token) {
        try {
            String userId = JWT.decode(token).getAudience().get(0);
            return userId;
        } catch (JWTDecodeException e) {
            return null;
        }
    }
    // 根據(jù)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和數(shù)據(jù)庫中是否一致,如不一致,直接返回失敗
        // 通過userName,password從數(shù)據(jù)庫中獲取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

前端結(jié)果:一串token字符串

訪問:http://localhost:8080/auth/info(以token作為header或者參數(shù))

后端結(jié)果

java.lang.NullPointerException: null
	at 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;
@Configuration
public 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;
@Slf4j
public 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;
        }
        // 頭部和參數(shù)都查看一下是否有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;
    }
}

到此這篇關(guān)于Spring攔截器中注入Bean失敗解放方案詳解的文章就介紹到這了,更多相關(guān)Spring Bean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

樟树市| 临清市| 滦南县| 囊谦县| 高台县| 凤冈县| 鲁山县| 壤塘县| 望奎县| 贡觉县| 盐源县| 正蓝旗| 鄂托克旗| 石景山区| 五家渠市| 横峰县| 新化县| 台中县| 万盛区| 平谷区| 郎溪县| 东安县| 读书| 崇明县| 新丰县| 和林格尔县| 台东市| 湘潭市| 宁陕县| 尖扎县| 沙雅县| 新乡县| 内乡县| 古浪县| 姜堰市| 西乌珠穆沁旗| 正安县| 铜梁县| 河南省| 麻栗坡县| 南开区|