web-dev-qa-db-fra.com

Pourquoi cette application Spring avec une configuration basée sur Java ne fonctionne pas correctement

J'ai récemment démarré un projet avec le framework Spring avec l'objectif de le développer sans aucun fichier de configuration XML, uniquement du code Java.

En ce moment, j'ajoute les fichiers suivants à mon projet:

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

Dans cet état, lorsque j'exécute l'application (dans Eclipse), le navigateur affiche le formulaire de connexion par défaut de Spring Security, ainsi qu'une erreur 404 après l'envoi de ce formulaire. Si j'essaie d'entrer directement l'url localhost: 8080/spring/index, je peux accéder à la page qui devrait apparaître après le formulaire de connexion.

Si j'ajoute cette classe:

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("/");
    }

}

En remplacement de web.xml, en suivant les instructions de la documentation officielle, dans ce lien:

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

Je ne peux même pas accéder à la page de connexion. La même chose se produit si j'ajoute à la classe SecurityConfig la méthode:

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

Quelqu'un peut voir ce qui me manque?

ps .:

Mon contrôleur est ceci:

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

METTRE À JOUR

Cette erreur est affichée dans la console d'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)

Après avoir répondu à cette rubrique, j'essaie de supprimer l'un des deux enregistrements en conflit de l'enregistrement de ContextListeners, de SecurityWebApplicationInitializer ou de WebAppInitializer. Dans les deux cas, j'obtiens cette erreur:

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
16
Kleber Mota
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!

Dans votre WebAppInitializer, vous enregistrez une ContextLoaderListener.

Parce que vous utilisez AbstractSecurityWebApplicationInitializer avec le constructeur superqui accepte un Class[]

Crée une nouvelle instance qui instanciera ContextLoaderListener avec les classes spécifiées.

qui enregistre également une ContextLoaderListener. Notez la classe javadoc

Lorsqu'il est utilisé avec AbstractSecurityWebApplicationInitializer(Class...), it enregistrera également une ContextLoaderListener. Lorsqu'il est utilisé avec AbstractSecurityWebApplicationInitializer(), cette classe est généralement utilisé en plus d'une sous-classe de AbstractContextLoaderInitializer.

Lorsque l’erreur indique, vous ne pouvez pas avoir deux instances ContextLoaderListener car elles essaieront toutes deux de créer et d’ajouter une ApplicationContext à la ServletContext.

15

Je pense que le problème est que ceci:

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

devrait être ceci:

.loginPage("/spring/index").permitAll() //note the '/' at the beginning of the uri
0
mario

J'ai eu un cours 

MyContextLoaderListener étend ContextLoaderListener

quelque part dans mon code. C'était inutilisé. La botte de printemps a apparemment utilisé la réflexion pour la trouver. J'ai supprimé le fichier et le problème avait disparu

0
ropo

Peut-être existe-t-il un chevauchement conflictuel entre votre web.xml et le configuration class basé sur Java. C'est la cause première lorsque j'ai rencontré la même erreur que vous. Et ma solution est de commenter la configuration dupliquée dans web.xml.

0
smwikipedia