Я пытаюсь 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");
}
Конечно, это будет «нуль» ... Вы делаете «новый JwtFilter» самостоятельно, без весны, ничего не делаете, никакой инъекции зависимостей. Вместо этого определите метод '@ Bean'. –
@ M.Deinum - Да! Так оно и было. Является лучшей альтернативой созданию '@ bean' (который просто возвращает новый JwtFilter) или делает то, что предлагает принятый ответ (который также работает)? – James111
Вы можете сделать оба, поскольку вы добавили '@ Component', он будет обнаружен. Однако imho лучше ввести его в метод 'jwtFilter (JwtFilter jwtFilter)'. Лучше переименуйте свой 'FilterRegistrationBean', так как теперь он переопределит фактический фильтр. Это приведет к странным проблемам отладки. –