2010-07-22 10 views
7

Estoy intentando configurar mi aplicación web sin XML y seguir la ruta anotada. Tengo unas pocas clases anotadas con @Configuration y @Component que se recogen automáticamente, pero por alguna razón mis anotaciones @Controller no se reconocen y asignan a sus valores @RequestMapping correspondientes.Spring 3 Annotated Configuration Selecciona @Configuration y @Component pero no @Controller

Mi archivo web.xml se ve así:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app id="com-timbuk2-webapp-compositor" 
     version="3.0" 
     xmlns="http://java.sun.com/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" > 

    <display-name>timbuk2-webapp-Compositor</display-name> 

    <!-- Context Parameters --> 
    <context-param> 
     <param-name>log4jConfigLocation</param-name> 
     <param-value>/WEB-INF/conf/log4j-config.xml</param-value> 
    </context-param> 

    <context-param> 
     <param-name>contextClass</param-name> 
     <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> 
    </context-param> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>com.company.webapp</param-value> 
    </context-param> 

    <!-- Listeners --> 
    <listener> 
     <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
    </listener> 

    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

    <!-- Filters --> 
    <filter> 
     <filter-name>characterEncodingFilter</filter-name> 
     <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 
     <init-param> 
      <param-name>encoding</param-name> 
      <param-value>UTF-8</param-value> 
     </init-param> 
     <init-param> 
      <param-name>forceEncoding</param-name> 
      <param-value>true</param-value> 
     </init-param> 
    </filter> 

    <filter> 
     <filter-name>urlRewriteFilter</filter-name> 
     <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> 
     <init-param> 
      <param-name>logLevel</param-name> 
      <param-value>commons</param-value> 
     </init-param> 
     <init-param> 
      <param-name>confPath</param-name> 
      <param-value>/WEB-INF/conf/urlrewrite-config.xml</param-value> 
     </init-param> 
    </filter> 

    <!-- Filter Mappings --> 
    <filter-mapping> 
     <filter-name>characterEncodingFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <filter-mapping> 
     <filter-name>urlRewriteFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <!-- Servlets --> 
    <servlet> 
     <servlet-name>dispatcher</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    </servlet> 

    <!-- Servlet mappings --> 
    <servlet-mapping> 
     <servlet-name>dispatcher</servlet-name> 
     <url-pattern>/app/*</url-pattern> 
    </servlet-mapping> 


</web-app> 

Mi clase principal @Configuration se ve así:

package com.company.webapp.config; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.support.ReloadableResourceBundleMessageSource; 
import org.springframework.web.servlet.view.InternalResourceViewResolver; 
import org.springframework.web.servlet.view.JstlView; 

@Configuration 
public class ApplicationConfiguration 
{  
    @Bean 
    public ReloadableResourceBundleMessageSource messageSource() 
    { 
     ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); 
     messageSource.setBasename("/WEB-INF/resources/messages"); 
     messageSource.setCacheSeconds(0); 
     return messageSource; 
    } 

    @Bean 
    public InternalResourceViewResolver viewResolver() 
    { 
     InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 
     viewResolver.setViewClass(JstlView.class); 
     viewResolver.setPrefix("/WEB-INF/views/"); 
     viewResolver.setSuffix(".jsp"); 
     return viewResolver; 
    } 
} 

Mi @Controller y @Component clases todos viven bajo el mismo paquete. Por ejemplo, aquí está una clase @Controller de mi aplicación:

package com.company.webapp.controller; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.stereotype.Controller; 
import org.springframework.validation.BindingResult; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.servlet.ModelAndView; 

@Controller 
@RequestMapping(value = "/render") 
public class RenderController 
{ 
    private final Logger logger = LoggerFactory.getLogger(getClass()); 

    @RequestMapping(method = RequestMethod.GET) 
    public ModelAndView handleGet(BindingResult bindingResult) 
    { 
     ... eventually return a ModelAndView object... 
    } 
} 

Así que reiterar, mis clases @Controller no se asignan a las direcciones URL que estoy especificando. Cuando la aplicación se inicia o vuelve a cargar en mi entorno local de tomcat, no veo la salida habitual de la consola "URL asignada"/procesamiento "a ...".

¿Alguien puede decirme qué me falta para evitar que mis clases anotadas de @Controller no se encuentren ni se registren?

+0

Debe agregar un único nombre base: messageSource.setBasename ("/ WEB-INF/resources/messages"); ¿Cómo agregar múltiples basenames con messageSource.setBasenames()? Dice una matriz de basenames, pero no estoy seguro de cómo poner una matriz en param. – Rihards

Respuesta

5

supongo que esto sucede porque @Controller s deben ser recogidos por DispatcherServlet de su propio contexto de aplicación (que se carga desde <servletname>-servlet.xml por defecto), cuando su contextClass y contextConfigLocation se aplican al contexto raíz (uno del ContextLoaderListener 's, que se carga desde applicationContext.xml de manera predeterminada).

Para configurar contexto de aplicación DispatcherServlet s, debe establecer contextClass y contextConfigLocation como init-param s del servlet.

EDIT: Este comportamiento es controlado por la propiedad detectHandlersInAncestorContexts de DefaultAnnotationHandlerMapping, por lo que el enfoque alternativo es configurarlo para true durante la configuración:

@Bean 
public DefaultAnnotationHandlerMapping mapping() { 
    DefaultAnnotationHandlerMapping m = new DefaultAnnotationHandlerMapping(); 
    m.setDetectHandlersInAncestorContexts(true); 
    return m; 
} 
+0

Establecí los parámetros contextClass y contextConfigLocation del servlet dispatcher en los mismos valores que la aplicación web. Todo parece estar bien, creo que ahora estoy un poco confundido. ¿Hay dos contextos ejecutándose ahora? Antes, cuando estaba haciendo toda la configuración XML, las asignaciones de URL se registraban cuando comenzaba o recargaba la aplicación web. Ahora no se asignan hasta que se realiza la primera solicitud entrante. –

+0

1) Sí, tiene dos contextos de aplicación: el contexto raíz y el contexto del Servidor Dispatcher, que es un elemento secundario de la raíz. Esto es típico de las aplicaciones de Spring MVC, consulte http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-servlet. Sin embargo, no es una buena idea hacer que carguen la configuración basada en anotaciones del mismo paquete, los beans se duplicarían. 2) El contexto de DispatcherServlet se inicializa cuando se carga el servlet, por lo que puede controlarlo con ''. 3) Agregué la solución alternativa. – axtavt

+0

Ahhhh ... Creo que finalmente entiendo ahora. Muchas gracias. –

1

Añadir esto en su despachador MVC archivo servlet XML donde el paquete debe ser para que todos los controladores sean escaneados para @controller o @Component.

<context:component-scan 
     base-package="packagesseperatedbycomma" /> 
+0

específicamente dijo que quiere configuración xml-less – Levancho

1

que fija esta cuestión, pero añadiendo el siguiente código a mi web.xml:

<servlet> 
     <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <init-param> 
      <param-name>contextClass</param-name> 
      <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> 
     </init-param> 
     <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>org.xxxx.inquiry.config, org.xxxx.inquiry.controller</param-value> 
     </init-param> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

Pero hacer esto lo digo dónde buscar mis controladores

Cuestiones relacionadas