为什么这个具有基于Java配置的Spring应用程序无法正常工作

我最近用Spring框架开始了一个项目,目的是在没有XML配置文件,只有Java代码的情况下开发它。

目前,我将以下文件添加到我的项目中:

WebAppConfig.java

@EnableWebMvc

@ComponentScan(value="org.webapp")

@Configuration

public class WebAppConfig extends WebMvcConfigurerAdapter {

@Override

public void addResourceHandlers(ResourceHandlerRegistry registry) {

registry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(31556926);

registry.addResourceHandler("/css/**").addResourceLocations("/fonts/").setCachePeriod(31556926);

registry.addResourceHandler("/img/**").addResourceLocations("/image/").setCachePeriod(31556926);

registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(31556926);

}

@Override

public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {

configurer.enable();

}

@Bean

public InternalResourceViewResolver getInternalResourceViewResolver() {

InternalResourceViewResolver resolver = new InternalResourceViewResolver();

resolver.setPrefix("/WEB-INF/jsp/");

resolver.setSuffix(".jsp");

return resolver;

}

}

SecurityConfig.java

@Configuration

@EnableWebSecurity

public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired

public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

auth

.inMemoryAuthentication()

.withUser("kleber").password("123").roles("USER");

}

}

SecurityWebApplicationInitializer.java

@Order(value=2)

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

public SecurityWebApplicationInitializer() {

super(SecurityConfig.class);

}

}

在这种状态下,当我运行应用程序(在Eclipse中)时,浏览器将显示Spring Security的默认登录表单,并在提交此表单后显示错误404。如果尝试直接输入URL localhost:8080 / spring / index,则可以访问登录表单后显示的页面。

如果我添加此类:

WebAppInitializer.java

@Order(value=1)

public class WebAppInitializer implements WebApplicationInitializer {

@Override

public void onStartup(ServletContext container) {

// Create the 'root' Spring application context

AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

rootContext.register(WebAppConfig.class);

// Manage the lifecycle of the root application context

container.addListener(new ContextLoaderListener(rootContext));

// Create the dispatcher servlet's Spring application context

AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();

dispatcherContext.register(DispatcherConfig.class);

// Register and map the dispatcher servlet

ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));

dispatcher.setLoadOnStartup(1);

dispatcher.addMapping("/");

}

}

要替换web.xml,请按照官方文档中的说明在此链接中:

http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/WebApplicationInitializer.html

我什至无法访问登录页面。如果将方法添加到类SecurityConfig中,也会发生相同的事情:

protected void configure(HttpSecurity http) throws Exception {

http

.authorizeRequests()

.antMatchers("/css/**", "/fonts/**", "/image/**", "/js/**").permitAll()

.anyRequest().authenticated()

.and()

.formLogin()

.loginPage("spring/index").permitAll()

.failureUrl("spring/erro_login").permitAll()

.defaultSuccessUrl("spring/home")

.and()

.logout()

.logoutSuccessUrl("spring/logout")

.permitAll();

}

有人可以看到我在想什么吗?

ps:

我的控制者是这样的:

@Controller

@RequestMapping(value="spring")

public class SpringController {

@RequestMapping(value="index")

public ModelAndView index() {

ModelAndView mav = new ModelAndView();

mav.setViewName("index");

return mav;

}

@RequestMapping(value="home")

public ModelAndView home() {

ModelAndView mav = new ModelAndView();

mav.setViewName("home");

return mav;

}

@RequestMapping(value="erro_login")

public ModelAndView erro_login() {

ModelAndView mav = new ModelAndView();

mav.setViewName("erro_login");

return mav;

}

@RequestMapping(value="erro_nao_autorizado")

public ModelAndView erro_nao_autorizado() {

ModelAndView mav = new ModelAndView();

mav.setViewName("erro_nao_autorizado");

return mav;

}

@RequestMapping(value="logout")

public ModelAndView logout() {

ModelAndView mav = new ModelAndView();

mav.setViewName("index");

return mav;

}

}

更新

在Eclipse的控制台中显示此错误

Mar 29, 2014 1:28:02 PM org.apache.catalina.core.StandardContext listenerStart

Grave: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener

java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!

at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:265)

at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)

at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4937)

at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)

at java.util.concurrent.FutureTask.run(FutureTask.java:262)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

at java.lang.Thread.run(Thread.java:744)

在给出此主题的答案之后,我尝试从SecurityWebApplicationInitializer或WebAppInitializer中删除ContextListener的两个有冲突的注册之一。在两种情况下,我都会收到此错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.servlet.Filter org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain() throws java.lang.Exception] threw exception; nested exception is java.lang.IllegalArgumentException: 'spring/index?error' is not a valid redirect URL

at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:581)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1025)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:921)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)

at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)

at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)

at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)

at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)

at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)

at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4937)

at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)

at java.util.concurrent.FutureTask.run(FutureTask.java:262)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

at java.lang.Thread.run(Thread.java:744)

Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.servlet.Filter org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain() throws java.lang.Exception] threw exception; nested exception is java.lang.IllegalArgumentException: 'spring/index?error' is not a valid redirect URL

at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:181)

at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)

... 23 more

Caused by: java.lang.IllegalArgumentException: 'spring/index?error' is not a valid redirect URL

at org.springframework.util.Assert.isTrue(Assert.java:65)

at org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler.setDefaultFailureUrl(SimpleUrlAuthenticationFailureHandler.java:98)

at org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler.<init>(SimpleUrlAuthenticationFailureHandler.java:43)

at org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer.failureUrl(AbstractAuthenticationFilterConfigurer.java:199)

at org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer.updateAuthenticationDefaults(AbstractAuthenticationFilterConfigurer.java:345)

at org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer.loginPage(AbstractAuthenticationFilterConfigurer.java:285)

at org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer.loginPage(FormLoginConfigurer.java:181)

at org.webapp.security.SecurityConfig.configure(SecurityConfig.java:27)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:192)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:276)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:61)

at org.webapp.security.SecurityConfig$$EnhancerByCGLIB$$f93abbff.init(<generated>)

at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:369)

at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:322)

at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:39)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:92)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$93d7a5f4.CGLIB$springSecurityFilterChain$0(<generated>)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$93d7a5f4$$FastClassByCGLIB$$eb934d27.invoke(<generated>)

at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)

at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:286)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$93d7a5f4.springSecurityFilterChain(<generated>)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:606)

at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)

... 24 more

Mar 29, 2014 4:18:30 PM org.apache.catalina.core.StandardContext listenerStart

Grave: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.servlet.Filter org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain() throws java.lang.Exception] threw exception; nested exception is java.lang.IllegalArgumentException: 'spring/index?error' is not a valid redirect URL

at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:581)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1025)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:921)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)

at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)

at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)

at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)

at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)

at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)

at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4937)

at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)

at java.util.concurrent.FutureTask.run(FutureTask.java:262)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

at java.lang.Thread.run(Thread.java:744)

Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.servlet.Filter org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain() throws java.lang.Exception] threw exception; nested exception is java.lang.IllegalArgumentException: 'spring/index?error' is not a valid redirect URL

at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:181)

at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)

... 23 more

Caused by: java.lang.IllegalArgumentException: 'spring/index?error' is not a valid redirect URL

at org.springframework.util.Assert.isTrue(Assert.java:65)

at org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler.setDefaultFailureUrl(SimpleUrlAuthenticationFailureHandler.java:98)

at org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler.<init>(SimpleUrlAuthenticationFailureHandler.java:43)

at org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer.failureUrl(AbstractAuthenticationFilterConfigurer.java:199)

at org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer.updateAuthenticationDefaults(AbstractAuthenticationFilterConfigurer.java:345)

at org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer.loginPage(AbstractAuthenticationFilterConfigurer.java:285)

at org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer.loginPage(FormLoginConfigurer.java:181)

at org.webapp.security.SecurityConfig.configure(SecurityConfig.java:27)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:192)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:276)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:61)

at org.webapp.security.SecurityConfig$$EnhancerByCGLIB$$f93abbff.init(<generated>)

at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:369)

at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:322)

at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:39)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:92)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$93d7a5f4.CGLIB$springSecurityFilterChain$0(<generated>)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$93d7a5f4$$FastClassByCGLIB$$eb934d27.invoke(<generated>)

at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)

at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:286)

at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$93d7a5f4.springSecurityFilterChain(<generated>)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:606)

at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)

... 24 more

回答:

java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!

在你的WebAppInitializer,要注册ContextLoaderListener

由于你使用AbstractSecurityWebApplicationInitializersuper 构造函数接受Class[]

创建一个新实例,该实例将使用指定的类实例化ContextLoaderListener。

也会注册一个ContextLoaderListener。注意类javadoc

与一起使用时AbstractSecurityWebApplicationInitializer(Class...),也会注册一个ContextLoaderListener。与一起使用时 AbstractSecurityWebApplicationInitializer(),通常会与的子类一起使用此类AbstractContextLoaderInitializer。

由于错误状态,你不能有两个ContextLoaderListener实例,因为它们都将尝试创建并将其添加ApplicationContext到中ServletContext

以上是 为什么这个具有基于Java配置的Spring应用程序无法正常工作 的全部内容, 来源链接: utcz.com/qa/401433.html

回到顶部