Попробуйте в JAVA Spring, сервис @AutoWired Filter, но выдает NPE

Мой проект использует структуру Spring для обработки http-запроса и ответа. У меня есть запрос, который заменяет некоторые параметры значением из редиса или базы данных, зависящей от одного из параметров.

Я рассматриваю большинство связанных случаев, которые используют фильтр для достижения цели.

Например, есть два параметра customerName:abc, isNickName:true API. И я пытаюсь реализовать класс, который расширяет класс OncePerRequestFilter, как показано ниже.

@Component("myFilter")
public class ConvertNickNameToRealNameFilter extends OncePerRequestFilter{

  @AutoWired
  private CustomerDao customerDao;

  @AutoWired
  private CustomerRepository customerRepository;

  protected abstract void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

    ...
    If (isNickName){
      customerName = getRealName(customerName); 
    }
    chain.doFilter(request, response);
    ...

  }

  // repo = repository = redis
  // dao = database
  public String getRealName(String nickName){
    String realName = customerRepository.getRealName(nickName);
    if(realName == null) {
      Customer c = customerDao.findByNickName(nickName);
      if(c != null){
        customerRepository.set(nickName, c.getRealName());
        return (c == null) ? "" : c.getRealName();
      }
    }else{
      return realName;
    }
  }
}

в веб.xml

<filter>
  <filter-name>myFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>myFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Я попытался использовать аннотацию @AutoWired для внедрения dao и репо, но не смог. Как справиться с тем, что дао и репо являются нулевыми? Любая подсказка будет приветствоваться, и образец кода будет идеальным.

Спасибо вам за помощь.


Наконец, я нашел способ заставить его работать, который использует DelegatingFilterProxy в классе фильтра вместо самого класса.

Можно увидеть код выше, который является основным блоком.


person Mayz    schedule 27.08.2020    source источник


Ответы (1)


Может быть много причин, по которым он нулевой. Я бы проверил следующее:

  1. Автосвязывание в spring происходит только в том случае, если сам класс (ConvertNickNameToRealNameFilter) управляется spring. Я вижу, что вы поместили в него Компонент, но такой код, как chain.doFilter, может намекать на то, что вы на самом деле используете технологию фильтрации сервлета Java, которая не интегрирована с Spring MVC (на самом деле Spring MVC построен поверх низкоуровневого сервлеты).

  2. Возможно, что класс не помещен в пакет, который не обрабатывается процессом сканирования компонентов Spring - так что spring его не загружает, код вообще входит в него?

  3. Если всем управляет spring, убедитесь, что репозитории и фильтр не обрабатываются в другом контексте приложения.

В общем, я предлагаю использовать перехватчики Spring mvc, а не простые фильтры. Они интегрированы с Spring MVC. См. эту ссылку, чтобы узнать о различиях между ними

person Mark Bramnik    schedule 28.08.2020
comment
Привет, Марк, спасибо за щедрый ответ. 1. Да, фильтр основан на селвете, и я хочу интегрировать его в Spring MVC. И, наконец, я пытаюсь использовать DelegatingFilterProxy для его реализации. 2. весь код входит в один проект. 3. только один контекст приложения, и похоже, что предыдущая конфигурация не применяется в контексте весны. И я бы прочитал информацию, которой вы поделились. - person Mayz; 28.08.2020