在扩展GenericFilterBean的过滤器中,Autowired字段为null

时间:2016-06-29 11:25:57

标签: java spring spring-boot spring-bean

我正在尝试 自动装配 服务 到我的请求过滤器。它给了我一个空指针异常,我不太清楚为什么。我在 控制器 中使用了完全相同的autowire类,它按预期工作!

@Component(value="jwtFilter")
public class JwtFilter extends GenericFilterBean {
    RedisClient redisClient = new RedisClient();

    @Autowired
    JwtTokenService jwtServ; // Is null for some reason??!!

    @Override
    public void doFilter(final ServletRequest req,
                         final ServletResponse res,
                         final FilterChain chain) throws IOException, ServletException {
//        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); // Doesnt fix issue
        System.out.println("\nMaking request...");
        final HttpServletRequest request = (HttpServletRequest) req;


        final String authHeader = request.getHeader("Authorization");
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            throw new ServletException("Missing or invalid Authorization header.");
        }

        final String token = authHeader.substring(7); // The part after "Bearer "

        try {
            final Claims claims = Jwts.parser().setSigningKey("${userapi.secret}")
                    .parseClaimsJws(token).getBody();
            request.setAttribute("claims", claims);
            request.setAttribute("token", token);
            System.out.println(claims.getSubject() + " <~~ Subject from jwt");
            JwtToken foundT = jwtServ.findByUser(claims.getSubject()); // Fails here because of jwtServ being null
            System.out.println (foundT + " <~~ Found JWT from redis");

        }
        catch (final SignatureException e) {
            throw new ServletException("Invalid token.");
        }


        chain.doFilter(req, res);
    }

有没有我错过的东西?我不确定为什么它可以在 spring controller 中工作,而不是 过滤器

这是我的所有 @Beans 的主要课程:

@SpringBootApplication
public class UserServiceApplication {
@Bean
    public FilterRegistrationBean jwtFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new JwtFilter());
        registrationBean.addUrlPatterns("/api/v1/*");
        registrationBean.addUrlPatterns("/user/api/v1/*");
        return registrationBean;
    }

    private @Value("${redis.host}") String redisHost;
    private @Value("${redis.port}") int redisPort;

    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }

    @Bean
    public HibernateJpaSessionFactoryBean sessionFactory() {
        return new HibernateJpaSessionFactoryBean();
    }


    @Bean
    JedisConnectionFactory jedisConnectionFactory() {
        JedisConnectionFactory jedisConFactory = new JedisConnectionFactory();
        jedisConFactory.setHostName("localhost");
        jedisConFactory.setPort(6379);
        return jedisConFactory;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(jedisConnectionFactory());
        return template;
    }



    @Bean
    ChannelTopic topic() {
        return new ChannelTopic("pubsub:queue");
    }

1 个答案:

答案 0 :(得分:2)

由于您手动实例化JwtFilter

registrationBean.setFilter(new JwtFilter());

Spring并没有管理它,因此没有注入jwtServ

要解决此问题,请将jwtFilter注入UserServiceApplication并将jwtFilter注入registrationBean

@SpringBootApplication
public class UserServiceApplication {

    @Autowired
    private JwtFilter jwtFilter;

    @Bean
    public FilterRegistrationBean jwtFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(jwtFilter);
        ...
    }
    ...