Используете некоторые bean-компоненты в классе bean-компонентов Filter? - PullRequest
17 голосов
/ 05 сентября 2010

В своем классе bean-компонента фильтра я добавил некоторую зависимость bean-компонента (с аннотацией @Autowired). Но в методе doFilter() все мои bean-компоненты зависимости имеют значение null ...

public class FacebookOAuth implements Filter
{
@Autowired
private BusinessLogger logger;

@Autowired
private IUserSessionInfo userSessionInfo;

@Autowired
private FacebookOAuthHelper oAuthHelper;

public void init(FilterConfig fc) throws ServletException
{
    // Nothing to do
}

public void doFilter(ServletRequest sr, ServletResponse sr1, FilterChain fc) throws   IOException, ServletException
{
    // HttpServletRequest req = (HttpServletRequest)sr;
    HttpServletResponse res = (HttpServletResponse) sr1;

    String code = sr.getParameter("code");

    if (StringUtil.isNotBlankStr(code))
    {
        String authURL = this.oAuthHelper.getAuthURL(code);

this.oAuthHelper равно нулю (и другим компонентам зависимости) ...

Не могли бы вы мне помочь?


На самом деле я не использую понятие MVC на стороне сервера (Spring). Для моего стороннего клиента я использую технологию Flex, а сервлет BlazeDS связывается с моим сервером.

Итак, вот почему я использую понятие bean-компонента Filter.

Итак, как мне справиться с понятием моего сессионного компонента в моем компоненте Filter?


Skaffman

Я реализовал вашу идею, поэтому я обновляю свой application.xml:

<bean id="FacebookOAuthHandler" class="com.xx.FacebookOAuthHandler" />
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
    <props>
       <prop key="/fbauth">FacebookOAuthHandler</prop>         
    </props>
   </property>
</bean>

и мой FacebookOAuthHandler класс:

public class FacebookOAuthHandler extends AbstractController
{
@Autowired
private BusinessLogger logger;

@Autowired
private IUserSessionInfo userSessionInfo;

@Autowired
private FacebookOAuthHelper oAuthHelper;

@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request,
        HttpServletResponse response) throws Exception {

    // TODO

    return null;
}

Но этот метод handleRequestInternal никогда не вызывается, когда мой URL-адрес: http://xx.xx.xx.xx/MyApp/fbauth

Ответы [ 5 ]

33 голосов
/ 13 августа 2015

Я столкнулся с той же проблемой, и моя первая идея заключалась в том, чтобы вручную заставить Spring применить аннотацию @Autowired к фильтру, как предложено здесь

http://forum.springsource.org/showthread.php?60983-Autowiring-the-servlet-filter

Но мне не нравитсяидея жесткого кодирования имени бина в моем классе Java.

Я нашел более чистый способ, который также работает:

public void init(FilterConfig filterConfig) throws ServletException {
    SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,
            filterConfig.getServletContext());
}
13 голосов
/ 05 сентября 2010

Если предположить, что это Filter подключено к вашему web.xml, то это не сработает, поскольку Spring не управляет им, а управляет контейнером сервлета.Таким образом, такие вещи, как автопроводка, не будут работать.

Если вы хотите определить фильтр сервлета как Spring bean, вам нужно определить его в контексте корневого приложения веб-приложения (используя ContextLoaderListener в web.xml)и затем определяя DelegatingFilterProxy, который делегирует ваш bean-управляемый bean-компонент для выполнения работы.

Однако вам действительно нужен фильтр сервлета для этого?Что я знаю о материалах аутентификации Facebook, это может быть сделано так же легко с Spring HandlerInterceptor.Это будет значительно меньше работы по настройке, чем фильтр делегирования.

7 голосов
/ 02 октября 2014

Я знаю, что это старый вопрос, но нет примера использования DelegatingFilterProxy в текущих ответах, и один недавний вопрос с таким примером был помечен как дубликат для этого.

Таким образом, DelegatingFilterProxy - это специальный фильтр, который знает о корне ApplicationContext и передает его doFilter бобу.

Пример: MyFilter - это класс, реализующий Filter, а myFilter - это пружинаbean

<bean id=myFilter class="org.example.MyFilter ...>...</bean>

или в классе конфигурации

@Bean
public MyFilter myFilter() {
    MyFilter myFilter = new MyFilter();
    //initialization ...
    return myFilter;
}

В файле web.xml вы просто объявляете DelegatingFilterProxy с тем же именем, что и bean:

<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>

Таким образом, поскольку myBean является истинным bean-компонентом, его можно вводить обычным образом с другими bean-компонентами с аннотациями @Autowired, и его метод doFilter будет вызываться DelegatingFilterProxy.Поскольку вы можете использовать пружинные методы init и destroy, по умолчанию методы init и destroy не будут вызываться, если вы не укажете init-param-фильтр фильтра "targetFilterLifecycle" как "true".

7 голосов
/ 28 августа 2012

Посмотрите на этот ответ на сайте весны: http://forum.springsource.org/showthread.php?60983-Autowiring-the-servlet-filter

Вкратце - вы можете вручную заставить пружину применить аннотацию @Autowire к вашему фильтру:

public void init(FilterConfig filterConfig) throws ServletException {

    ServletContext servletContext = filterConfig.getServletContext();
    WebApplicationContext webApplicationContext = 
            WebApplicationContextUtils.getWebApplicationContext(servletContext);

    AutowireCapableBeanFactory autowireCapableBeanFactory =
           webApplicationContext.getAutowireCapableBeanFactory();

    autowireCapableBeanFactory.configureBean(this, BEAN_NAME);
}
1 голос
/ 22 октября 2016

Я получал нулевой указатель при доступе к бину класса обслуживания в классе фильтра с помощью Autowiring.Я искал более 100 ссылок, но не смог найти решение.Я использую Spring Boot Application и конфигурацию, которая требуется для получения bean-компонента в классе фильтра:

FilterConfig.java, который предоставляет объект контекста приложения.

@Component
public class FilterConfig  implements ApplicationContextAware{

private static ApplicationContext context;


public static ApplicationContext getApplicationContext() {
       return context;
    }
public  static <T> T getBean(String name,Class<T> aClass){
    return context.getBean(name,aClass);
}

@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
    context = ctx;
}   

 }

в классе Filter, я использовал это как:

 UserService userService =FilterConfig.getBean("UserService", UserService.class);

UserService - это имя компонента, которое упоминается в

  @Service("UserService")
  public class UserServiceImpl implements UserService { ...}

Нет Конфигурация в основном классе Spring. Загрузка: SpringBootServletInitializer

...