在过滤器 bean 类中使用一些 bean?

Posted

技术标签:

【中文标题】在过滤器 bean 类中使用一些 bean?【英文标题】:Using some beans in Filter bean class? 【发布时间】:2011-04-08 10:07:03 【问题描述】:

在我的过滤器 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)...

你能帮帮我吗?


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

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

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


斯卡夫曼,

我实现了你的想法,所以我更新了我的 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;

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

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

【问题讨论】:

你的 spring 配置是什么样的? 【参考方案1】:

假设这个Filter 连接在你的web.xml 中,那么这是行不通的,因为它不是由Spring 管理的,而是由servlet 容器管理的。所以像自动装配这样的东西就行不通了。

如果您想将 servlet 过滤器定义为 Spring bean,那么您需要在 webapp 的根应用程序上下文中定义它(在 web.xml 中使用 ContextLoaderListener),然后将 defining a DelegatingFilterProxy 委托给您的 Spring-托管 bean 来完成这项工作。

但是,您真的需要一个 servlet 过滤器吗?我对 Facebook auth 的了解,可能是done just as easily with a Spring HandlerInterceptor。与委托过滤器相比,这将大大减少配置工作。

【讨论】:

嗨,斯卡夫曼!非常感谢您的回答。是的,我所有的配置文件(web.xml 和我的 application.xml)都可以(使用 ContextLoaderListenner、使用 delegatingFilterProxy 等)。但是,即使使用这种配置,我也不能在过滤器中使用 bean,对吗? 你能给出一些代码示例如何将servlet过滤器定义为spring bean吗? 我其实看过pro-programmers.blogspot.co.il/2011/08/…的文章,但是我没有使用SpringMCV。会有帮助吗? 第一段很有意思。第二个没有说明如何使用 CLL 定义某些东西,也没有说明如何定义以及如何通过 DFP 委托。第三段也有同样的问题。 HI 如何充当过滤器?应该如何以及在哪里注册?给出的参考是无用的——它们是简单的文档链接,我们可以很容易地通过类名搜索自己。并且没有回答提到的任何问题。所以,答案相当空洞。【参考方案2】:

春天现场看这个答案:http://forum.springsource.org/showthread.php?60983-Autowiring-the-servlet-filter

简而言之 - 您可以手动强制 spring 将 @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】:

我知道这是一个现在很老的问题,但在当前的回复中没有使用 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 方法,除非您将“targetFilterLifecycle”过滤器init-param 指定为“true”。

【讨论】:

我正在尝试在我的项目中执行此操作,但在服务器启动时,会引发错误:严重:异常启动过滤器 myFilter org.springframework.beans.factory.NoSuchBeanDefinitionException:没有名为 'myFilter 的 bean ' 被定义为。我尝试通过 XML 和 Annotation 进行配置。似乎在配置bean之前读取了web.xml。 我在很多项目中都使用过它,从来没有遇到过任何问题。但是 bean 必须在根上下文中声明,而不是在 dispatcher-servlet 之一中声明。你应该展示你如何声明你的bean。 我很抱歉我的新手,但是我如何在 root 或 dispatcher-servlet 上下文中声明一个 bean?我刚刚创建了一个配置类,我在其中放置了一个“@Configuration”注释,然后创建了一个“@Bean”(指的是 myFilter 类)。 @Alex 好的,所以它应该在根上下文中。 Spring 配置的其余部分是否正常工作,它是如何声明的? @Alex : 重要的是包被扫描了......无论如何,将配置类放在一个包中,在那里你有其他正确处理的配置类。【参考方案4】:

我遇到了同样的问题,我的第一个想法是手动强制 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());

【讨论】:

引用已失效。 2019年整个论坛闭馆,有没有积极的参考。请问?【参考方案5】:

在使用 Autowiring 访问过滤器类中的服务类 bean 时,我得到了空指针。我搜索了 100 多个链接,但找不到解决方案。 我正在使用在过滤器类中获取 bean 所需的 Spring Boot 应用程序和配置:

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;
   

 

在过滤器类中,我这样使用:

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

UserService 这是

中提到的 bean 名称
  @Service("UserService")
  public class UserServiceImpl implements UserService  ...

spring Boot 主类没有配置:SpringBootServletInitializer

【讨论】:

以上是关于在过滤器 bean 类中使用一些 bean?的主要内容,如果未能解决你的问题,请参考以下文章

在 Web 过滤器中访问会话范围的 JSF 托管 bean

JAVA WEB 过滤器(Filter)中向容器 Spring 注入 bean

注册过滤器时@Bean和@Component的区别?

在 servlet 过滤器中设置托管 Bean 的值。 [关闭]

Spring 安全自定义过滤器(在 AuthenticationManager bean 已经存在时创建它的原因)

将过滤器 bean 添加到 ServletContext