在Filter bean类中使用一些bean?

时间:2010-09-05 09:51:01

标签: java spring servlets servlet-filters

在我的过滤器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 等于null(以及其他依赖bean)...

你能帮帮我吗?


实际上我并没有在服务器端使用MVC概念(Spring)。对于我的客户,我使用Flex技术,BlazeDS servlet与我的服务器通信。

所以,这就是我使用Filter bean概念的原因。

那么,如何在我的Filter bean中处理会话bean概念?


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

但是,当我的网址为:http://xx.xx.xx.xx/MyApp/fbauth

时,永远不会调用此方法 handleRequestInternal

5 个答案:

答案 0 :(得分:33)

我遇到了同样的问题,我的第一个想法是手动强制Spring将@Autowired注释应用到像这里提出的过滤器

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

但我不喜欢在我的Java类中硬编码bean名称的想法。

我找到了一种更清洁的方式:

public void init(FilterConfig filterConfig) throws ServletException {
    SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,
            filterConfig.getServletContext());
}

答案 1 :(得分:13)

假设Filter已连接到web.xml,那么这不会起作用,因为它不是由Spring管理的,而是由servlet容器管理的。因此,自动装配等功能将无效。

如果要将servlet过滤器定义为Spring bean,则需要在webapp的根应用程序上下文中定义它(使用web.xml中的ContextLoaderListener),然后defining a DelegatingFilterProxy代理你的Spring管理的bean来做这项工作。

但是,你真的需要一个servlet过滤器吗?我所知道的Facebook认证的东西,这可能是done just as easily with a Spring HandlerInterceptor。与委派过滤器相比,配置工作要少得多。

答案 2 :(得分:7)

在春天的网站上看看这个答案: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);
}

答案 3 :(得分:7)

我知道这是一个现在很老的问题,但是在当前的回复中没有使用DelegatingFilterProxy的例子,并且最近一个问这样一个例子的问题被标记为此问题的副本。

因此DelegatingFilterProxy是一个特殊的过滤器,它知道根ApplicationContext并将其doFilter委托给bean。

示例:MyFilter是一个实现Filter的类,myFilter是一个spring bean

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

或在配置类

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

在web.xml中,您只需声明一个与bean名称相同的DelegatingFilterProxy

<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,它可以正常注入其他具有@Autowired注释的bean,doFilter方法将调用DelegatingFilterProxy方法}。由于您可以使用spring init和destroy方法,因此默认情况下不会调用initdestroy方法,除非您指定&#34; targetFilterLifecycle&#34;将init-param过滤为&#34; true&#34;。

答案 4 :(得分:1)

在使用自动装配访问过滤器类中的服务类bean时,我获得了空指针。我搜索了100多个链接,但无法找到解决方案。 我正在使用spring引导应用程序和配置,这是在过滤器类中获取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这是bean名称,在

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

Spring Boot的主类中没有配置:SpringBootServletInitializer