2010-07-22 31 views
7

Vì vậy, tôi đang cố gắng định cấu hình ứng dụng web của mình mà không cần XML và đi tất cả tuyến đường được chú thích. Tôi có một vài lớp được chú thích với @Configuration và @Component được nhận tự động, nhưng vì một số lý do chú thích @Controller của tôi không được nhận dạng và ánh xạ tới các giá trị @RequestMapping tương ứng của chúng.Spring 3 Cấu hình chú thích Chọn lên @Configuration và @Component nhưng không @Controller

file web.xml của tôi trông giống như vậy:

<?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> 

lớp @Configuration chính của tôi trông giống như vậy:

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

My @Controller và @Component lớp đều sống dưới cùng một gói. Ví dụ: đây là lớp @Controller từ ứng dụng của tôi:

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... 
    } 
} 

Vì vậy, để nhắc lại, các lớp @Controller của tôi không được ánh xạ tới URL tôi chỉ định. Khi ứng dụng khởi động hoặc tải lại trong môi trường tomcat cục bộ của tôi, tôi không nhìn thấy đầu ra của giao diện điều khiển "Ánh xạ URL"/render "thông thường".

Bất cứ ai có thể cho tôi biết những gì tôi đang thiếu có thể ngăn không cho các lớp được chú thích @Controller của tôi không được tìm thấy và đăng ký không?

+0

Bạn thêm một basename duy nhất: messageSource.setBasename ("/ WEB-INF/resources/messages"); Cách thêm nhiều tên nền với messageSource.setBasenames()? Nó nói mảng của các basenames, nhưng tôi không chắc chắn làm thế nào để đặt một mảng trong param. – Rihards

Trả lời

5

Tôi đoán điều này xảy ra bởi vì @Controller s nên được chọn bởi DispatcherServlet từ ngữ cảnh của nó riêng ứng dụng (được nạp từ <servletname>-servlet.xml theo mặc định), khi contextClass của bạn và contextConfigLocation được áp dụng cho bối cảnh gốc (một trong những 's ContextLoaderListener, mà được tải từ applicationContext.xml theo mặc định).

Để định cấu hình ngữ cảnh ứng dụng DispatcherServlet, bạn nên đặt contextClasscontextConfigLocation làm servlet init-param s.

EDIT: Hành vi này được điều khiển bởi thuộc tính detectHandlersInAncestorContexts của DefaultAnnotationHandlerMapping, vì vậy cách tiếp cận khác là để thiết lập nó để true trong cấu hình:

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

Tôi đặt các tham số contextClass và contextConfigLocation của servlet dispatcher thành các giá trị giống như webapp. Tất cả có vẻ tốt, tôi đoán bây giờ tôi là một chút bối rối mặc dù. Có hai ngữ cảnh đang chạy bây giờ không? Trước đây, khi tôi đang thực hiện tất cả cấu hình XML, ánh xạ URL sẽ đăng ký khi tôi bắt đầu hoặc tải lại ứng dụng web. Bây giờ họ không nhận được ánh xạ cho đến khi yêu cầu đầu tiên đầu tiên được thực hiện. –

+0

1) Có, bạn có hai ngữ cảnh ứng dụng - ngữ cảnh gốc và ngữ cảnh của DispatcherServlet, là một ngữ cảnh con của thư mục gốc. Điều này là điển hình cho các ứng dụng Spring MVC, xem http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-servlet. Tuy nhiên, nó không phải là một ý tưởng tốt để làm cho họ tải cấu hình dựa trên chú thích từ cùng một gói - đậu sẽ được nhân đôi. 2) Ngữ cảnh của DispatcherServlet được khởi tạo khi servlet được nạp, vì vậy bạn có thể kiểm soát bằng ''. 3) Tôi đã thêm giải pháp thay thế. – axtavt

+0

Ahhhh ... Tôi nghĩ cuối cùng tôi đã hiểu rồi. Cảm ơn rất nhiều. –

1

Thêm này trong điều phối MVC của bạn tập tin servlet xml nơi gói phải dành cho tất cả các trình điều khiển được quét cho @controller hoặc @Component.

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

anh ấy đặc biệt nói rằng anh ấy muốn cấu hình xml-less – Levancho

1

Tôi cố định vấn đề này nhưng thêm đoạn mã sau vào web.xml của tôi:

<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> 

Nhưng làm điều này tôi nói với nó nơi để tìm kiếm các bộ điều khiển của tôi

Các vấn đề liên quan