经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Redis » 查看文章
springboot拦截器无法注入redisTemplate的解决方法
来源:jb51  时间:2021/6/28 9:09:28  对本文有异议

在工作中我们经常需要做登录拦截验证或者其他拦截认证功能,基于springboot项目下我们很容易想到结合redis做的分布式拦截,把用户登录或者需要验证的信息放到redis里面。但是在写拦截器的时候发现redisTemplate一直无法注入进来,最后查资料才发现springboot拦截器是在Bean实例化之前执行的,所以Bean实例无法注入。

先看下问题,新建一个拦截器,然后注入redisTemplate

  1. /**
  2. * @author: lockie
  3. * @Date: 2019/8/13 16:16
  4. * @Description: 接口限流拦截器
  5. */
  6. @Component
  7. public class AccessLimitIntercept implements HandlerInterceptor {
  8. private static final Logger logger = LoggerFactory.getLogger(AccessLimitIntercept.class);
  9. @Autowired
  10. private StringRedisTemplate redisTemplate;
  11. /**
  12. * 接口调用前检查对方ip是否频繁调用接口
  13. * @param request
  14. * @param response
  15. * @param handler
  16. * @return
  17. * @throws Exception
  18. */
  19. @Override
  20. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  21. try {
  22. String test = redisTemplate.opsForValue().get("test");
  23. logger.info(test);
  24. } catch (Exception e) {
  25. logger.error("API请求限流拦截异常,异常原因:", e);
  26. throw new ParameterException(e);
  27. }
  28. return true;
  29. }
  30. @Override
  31. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  32. }
  33. @Override
  34. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  35. }
  36. private boolean setResponse(Results results, HttpServletResponse response) throws IOException {
  37. ServletOutputStream outputStream = null;
  38. try {
  39. response.setHeader("Content-type", "application/json; charset=utf-8");
  40. outputStream = response.getOutputStream();
  41. outputStream.write(JsonUtil.toJson(results).getBytes("UTF-8"));
  42. } catch (Exception e) {
  43. logger.error("setResponse方法报错", e);
  44. return false;
  45. } finally {
  46. if (outputStream != null) {
  47. outputStream.flush();
  48. outputStream.close();
  49. }
  50. }
  51. return true;
  52. }
  53. }

然后配置拦截器,新建一个拦截器config类,我们这里让所有的url都拦截

  1. @Configuration
  2. public class WebFilterConfig implements WebMvcConfigurer {
  3. /**
  4. * 多个拦截器组成一个拦截器链
  5. * @param registry
  6. */
  7. @Override
  8. public void addInterceptors(InterceptorRegistry registry) {
  9. registry.addInterceptor(new AccessLimitIntercept()).addPathPatterns("/**");
  10. }
  11. }

新建一个controller里面增加一个接口,使用postman调用接口

  1. @RestController
  2. @RequestMapping("/")
  3. public class PingController extends BaseController {
  4. @GetMapping(value = "/ping")
  5. public Results ping() {
  6. return succeed("pong", "");
  7. }
  8. }

使用postman调用/ping接口,发现返回系统错误

控制台发现是空指针的错误,定位错误发现当我们想获取redis里面key是test的值时,发现redisTemplate没有是空的没有注入进来

解决问题:

知道拦截器执行在bean实例化前执行的,那么我们就让拦截器执行的时候实例化拦截器Bean,在拦截器配置类里面先实例化拦截器,然后再获取

  1. @Configuration
  2. public class WebFilterConfig implements WebMvcConfigurer {
  3. /**
  4. * 这里需要先将限流拦截器入住,不然无法获取到拦截器中的redistemplate
  5. * @return
  6. */
  7. @Bean
  8. public AccessLimitIntercept getAccessLimitIntercept() {
  9. return new AccessLimitIntercept();
  10. }
  11. /**
  12. * 多个拦截器组成一个拦截器链
  13. * @param registry
  14. */
  15. @Override
  16. public void addInterceptors(InterceptorRegistry registry) {
  17. registry.addInterceptor(getAccessLimitIntercept()).addPathPatterns("/**");
  18. }
  19. }

使用postman再次请求就可以访问到

到此这篇关于springboot拦截器无法注入redisTemplate的解决方法的文章就介绍到这了,更多相关springboot拦截器无法注入redisTemplate内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号