0

按照 spring.io 上的指南 ( https://spring.io/guides/tutorials/web/6/ ),我正在将我的应用程序迁移到 Spring 4。如指南中所示,在使用 SecurityWebAppInitializer 后,我遇到了 NullPointerException。以下是跟踪堆栈:

java.lang.NullPointerException
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)

完整的堆栈如下:

Servlet.service() for servlet [dispatcher] in context with path [] threw exception
java.lang.NullPointerException
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)

错误堆栈没有显示太多信息。如何确定其原因并解决此错误?

我以与指南中所示相同的方式使用 Java 配置。WebAppInitializer 和 SecurityWebAppInitializer 与指南相同。

@Order(2)
public class WebAppInitializer extends
    AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[] { WebSecurityConfig.class, JPAConfig.class, CoreConfig.class, FacebookConfig.class };
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[] { WebConfig.class };
}

@Override
protected String[] getServletMappings() {
    return new String[] { "/" };
}

@Override
protected Filter[] getServletFilters() {

    CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
    characterEncodingFilter.setEncoding("UTF-8");
    return new Filter[] { characterEncodingFilter};
}

}

@Order(1)
public class SecurityWebAppInitializer
extends AbstractSecurityWebApplicationInitializer { }

以及 WebConfig.java 的一部分:

@Configuration
@EnableWebMvc
@PropertySource({ "classpath:mail.properties",
    "classpath:express.properties" })
@ComponentScan(basePackages = { "com.myapp.account.web" })
@Import({CoreConfig.class})
public class WebConfig extends WebMvcConfigurerAdapter {
   ....
}

和 WebSecurityConfig.java:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    ...
}

删除SecurityWebAppInitializer 或注释掉其父类AbstractSecurityWebApplicationInitializer 后不会发生异常。提前感谢您的投入。

4

2 回答 2

0

当您迁移到 Spring 4 时,您是否从 web.xml 中删除了springSecurityFilterChain? 您当前应用程序中的 spring 安全配置似乎干扰了基于注释的新配置。

即 Spring 安全的延迟过滤器代理配置了 null targetBeanName,这会导致空指针异常。SecurityWebAppInitializer如果只有发挥作用,这是不可能的。

您还可以在 DelegatingFilterProxy构造函数和 targetBeanName 的设置器中放置一些断点,以查看是谁将其设置为 null。

于 2014-02-20T21:21:31.350 回答
0

我得到了与默认 bean 名称被设置为 null 相同的异常,通过在 DelegatingFilterProxy 构造函数中将 bean 名称显式设置为“springSecurityFilterChain”解决了这个问题

@Override
protected Filter[] getServletFilters() {

    CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
    characterEncodingFilter.setEncoding("UTF-8");

    return new Filter[] { characterEncodingFilter, new DelegatingFilterProxy("springSecurityFilterChain")};
}
于 2015-08-18T06:42:49.917 回答