spring中配置过滤器的一个疑问。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring中配置过滤器的一个疑问。相关的知识,希望对你有一定的参考价值。

最近在项目中配置一个过滤器,因为这个过滤器中要用到一个业务类所以为它添加了这个业务类的属性,也写了getter和setter方法,并且在spring的xml文件中也对它进行了注入,但是调试的时候后台打印这个业务类为null。 现在请问大家是不是用spring整合了的过滤器中无法引用业务类(与过滤器的特性有关?),但是spring整合后更不能new出来啊。
@Proc_871113: 我们平时都是业务类类实现接口,然后在业务类中调用DAO的,在action中一直这样掉用都没问题,就是在过滤器中拿不到这个业务类。
@ms_compound:按照你说的去做了,后台打印还是null

嗯 ...楼主说的很明白,业务类(ServiceIMP)及注入,调用 都没有问题

既然项目中加入了filter 那么就是通过spring在filter注入bean

将filter注入Spring 而不是单纯的把业务类注入生成getter setter,让filter调用就可以了。在spring中,filter被纳入了bean 管理机制。

如Spring注入过滤器配置

<bean id="myFilter" class="com.MyFilter"> //指名具体的filter类
<property name="service"> //需要注入的具体参数
<ref bean="service"/>
</property>
</bean>

这样吧 这有个简单实例,给你参考一下:
http://www.iwangyu.com/index.php/archives/309

如果只凭配置信息看不明白,还有个简单的例子你看一下:
http://hi.baidu.com/anglee2010/blog/item/bc51ab3f11ffc13371cf6c28.html

应该差不多了...

工作日可以随时 Hi 我
参考技术A 你那个业务类是不是有继承关系?

ServiceA

private Dao

setDao

getDao

Service B extends ServiceA

如果是这种情况 子类一定不要复写 父类的 set get 方法
因为如果一旦复写,那么set get方法只是将 DAO注入到 子类中,父类并没有注入会出错。
参考技术B setter方法是自动生成的还是手写的?字段名是什么?命名是否规范?比如第二个字母有没有大写

在 Spring Boot 中配置 RequestContextListener

【中文标题】在 Spring Boot 中配置 RequestContextListener【英文标题】:Configuring RequestContextListener in SpringBoot 【发布时间】:2015-07-27 01:23:31 【问题描述】:

我有一个使用 Spring-Security 的 Spring-Boot 应用程序。我有一个请求范围的 bean,我想将它自动装配到安全过滤器链中的一个自定义过滤器中,但目前它不起作用。

我了解在 DispatcherServlet 之外使用请求范围的 bean 需要进行一些配置,并且已阅读此 http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-other 但尚未取得任何成功:

对于 Servlet 3.0+,这可以通过 WebApplicationInitializer 接口。

(我使用的是最新的 Tomcat,servlet 3+ 也是)

我尝试过同时使用 RequestContextListener 和 RequestContextFilter(文档说它们和 DispatcherServlet 执行完全相同的操作),但在这两种情况下我仍然会遇到错误,因为我的自动装配对象为空:

我尝试注册过滤器

@Configuration
@ComponentScan
@EnableAutoConfiguration
class Application extends SpringBootServletInitializer  

    @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) 
        application.sources( Application )
    

    @Override public void onStartup( ServletContext servletContext ) throws ServletException 
        super.onStartup( servletContext )
        servletContext.addFilter("requestContextFilter", new RequestContextFilter() ).addMappingForUrlPatterns(null, false, "/*")
    

我尝试注册监听器

@Configuration
@ComponentScan
@EnableAutoConfiguration
class Application extends SpringBootServletInitializer  

    @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) 
        application.sources( Application )
    

    @Override public void onStartup( ServletContext servletContext ) throws ServletException 
        super.onStartup( servletContext )
        servletContext.addListener( new RequestContextListener() ) 
    

我是否遗漏了一些明显的东西?我已经查看了 Spring Boot 的自动配置源代码,但还没有遇到任何东西。


更新

我是个白痴,我在我的 SpringSecurity 配置中添加了我的过滤器,在 configure() 方法中:

http.addFilterBefore( new PreAuthFilter(), BasicAuthenticationFilter )

但尚未将新过滤器注册为 Bean。根据下面 M. Denium 的评论,我不需要所有额外的配置显式添加侦听器/过滤器,只需注册 bean 就足够了。

【问题讨论】:

你让它变得复杂。只需添加一个构造RequestContextListener@Bean 方法。 Spring Boot 将完成剩下的工作。但是,由于 Spring 安全过滤器链受 Spring 控制,因此不需要这样做,因此除非您在实际过滤器链之外执行操作,否则您需要注册它,否则它应该可以工作。 谢谢@M.Deinum - 原来我是个白痴 - 我已经用细节更新了问题,但基本上没有正确注册过滤器。 @M.Deinum: 自定义AuthenticationProvider 是否被视为“在实际过滤器链之外”?如果没有,那么这样的提供者是否可以访问已初始化的 RequestContextHolder 而无需显式配置 RequestContextListener 【参考方案1】:

正如更新/cmets 中所详述的,这是我自己的愚蠢造成的。

Spring-Boot 能够将请求/会话范围的 bean 自动装配到 DispatcherServlet 之外的过滤器中。根据 Spring 的文档,我们需要添加 RequestContextListenerRequestContextFilter 以启用此功能:

在请求、会话和全局中支持 bean 的作用域 会话级别(网络范围的 bean),一些小的初始配置是 在定义 bean 之前需要。 (此初始设置不是 标准范围、单例和原型所需的。) ...

如果你在 Spring Web MVC 中访问作用域 bean,实际上是在一个 由 Spring DispatcherServlet 处理的请求,或 DispatcherPortlet,则无需特殊设置: DispatcherServlet 和 DispatcherPortlet 已经公开了所有相关的 状态。

为了处理这个问题,我需要注册一个 RequestContextListener bean:

@Bean public RequestContextListener requestContextListener()
    return new RequestContextListener();
 

如果您不注册该 bean,您将收到一条错误消息,指出您正在尝试访问 DispatcherServlet 之外的 Request 范围。

我遇到的问题(自动装配的对象没有被注入)是因为我只是将我的自定义过滤器注册为标准类实例,而不是 Spring 托管 bean:

http.addFilterBefore( new PreAuthFilter(), BasicAuthenticationFilter )

为了解决这个问题,我只是将 PreAuthFilter 的创建移到了单独的 @Bean 方法中,然后 @Autowired 功能就可以正常工作了。

【讨论】:

谢谢你,不要对自己太苛刻。愚蠢。你的问题和回答真的帮助了我。 谢谢,这对我也有帮助,但我没有注册 RequestContextFilter bean,而是在我的 ResourceServerConfigurerAdaptor 扩展中添加以下行:addFilterAfter(new RequestContextFilter(), CsrfFilter.class)

以上是关于spring中配置过滤器的一个疑问。的主要内容,如果未能解决你的问题,请参考以下文章

Spring OAuth 过滤器链和 Java 配置

shiro springmvc的controller要怎么写

关于web.xml中配置Spring字符编码过滤器以解决中文乱码的问题

在 Spring Boot 中配置 RequestContextListener

Spring中过滤器+监听器的使用

Spring JWT 过滤器配置