2016-06-29 5 views
-1

Я пытаюсь autowireслужба на мой запрос фильтра. Это дает мне исключение нулевого указателя, и я не совсем понимаю, почему. Я использовал тот же самый класс autowire в моем контроллер и он работает так, как ожидалось!Autowired поле нулевой фильтр, который простирается GenericFilterBean

@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); 
    } 

Есть ли что-то, что я пропустил? Я не уверен, почему это сработало бы в моем контроллер пружины, а не фильтр?

Вот мой основной класс со всеми @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"); 
    } 
+2

Конечно, это будет «нуль» ... Вы делаете «новый JwtFilter» самостоятельно, без весны, ничего не делаете, никакой инъекции зависимостей. Вместо этого определите метод '@ Bean'. –

+0

@ M.Deinum - Да! Так оно и было. Является лучшей альтернативой созданию '@ bean' (который просто возвращает новый JwtFilter) или делает то, что предлагает принятый ответ (который также работает)? – James111

+0

Вы можете сделать оба, поскольку вы добавили '@ Component', он будет обнаружен. Однако imho лучше ввести его в метод 'jwtFilter (JwtFilter jwtFilter)'. Лучше переименуйте свой 'FilterRegistrationBean', так как теперь он переопределит фактический фильтр. Это приведет к странным проблемам отладки. –

ответ

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); 
     ... 
    } 
    ... 
+0

Да! Я просто достиг этого, создав метод '@bean JwtFilter', а затем добавив это как« фильтр »... Это решение кажется лучшей альтернативой! – James111