2008-09-29 5 views
5

Я использую Spring 2.5 и использую аннотации для настройки контроллеров. Мой контроллер работает нормально, если я не реализую никаких дополнительных интерфейсов, но весенний контейнер не распознает отображение контроллера/запроса при добавлении реализаций интерфейса.Аннотированный контроллер Spring-MVC не распознается, когда контроллер расширяет интерфейс

Я не могу понять, почему добавление реализации интерфейса испортит конфигурацию контроллера и сопоставлений запросов. Есть идеи?

Таким образом, это работает:

package com.shaneleopard.web.controller; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.security.providers.encoding.Md5PasswordEncoder; 
import org.springframework.stereotype.Controller; 
import org.springframework.validation.Errors; 
import org.springframework.validation.Validator; 
import org.springframework.web.bind.annotation.ModelAttribute; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 

import com.shaneleopard.model.User; 
import com.shaneleopard.service.UserService; 
import com.shaneleopard.validator.RegistrationValidator; 
import com.shaneleopard.web.command.RegisterCommand; 

@Controller 
public class RegistrationController { 

    @Autowired 
    private UserService userService; 

    @Autowired 
    private Md5PasswordEncoder passwordEncoder; 

    @Autowired 
    private RegistrationValidator registrationValidator; 

    @RequestMapping(method = RequestMethod.GET, value = "/register.html") 
    public void registerForm(@ModelAttribute RegisterCommand registerCommand) { 
     // no op 
    } 

    @RequestMapping(method = RequestMethod.POST, value = "/register.html") 
    public String registerNewUser(@ModelAttribute RegisterCommand command, 
      Errors errors) { 
     String returnView = "redirect:index.html"; 

     if (errors.hasErrors()) { 
      returnView = "register"; 
     } else { 
      User newUser = new User(); 
      newUser.setUsername(command.getUsername()); 
      newUser.setPassword(passwordEncoder.encodePassword(command 
        .getPassword(), null)); 
      newUser.setEmailAddress(command.getEmailAddress()); 
      newUser.setFirstName(command.getFirstName()); 
      newUser.setLastName(command.getLastName()); 

      userService.registerNewUser(newUser); 
     } 
     return returnView; 

    } 

    public Validator getValidator() { 
     return registrationValidator; 
    } 
} 

, но это не делает:

package com.shaneleopard.web.controller; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.security.providers.encoding.Md5PasswordEncoder; 
import org.springframework.stereotype.Controller; 
import org.springframework.validation.Errors; 
import org.springframework.validation.Validator; 
import org.springframework.web.bind.annotation.ModelAttribute; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 

import com.shaneleopard.model.User; 
import com.shaneleopard.service.UserService; 
import com.shaneleopard.validator.RegistrationValidator; 
import com.shaneleopard.web.command.RegisterCommand; 

@Controller 
public class RegistrationController extends ValidatingController { 

    @Autowired 
    private UserService userService; 

    @Autowired 
    private Md5PasswordEncoder passwordEncoder; 

    @Autowired 
    private RegistrationValidator registrationValidator; 

    @RequestMapping(method = RequestMethod.GET, value = "/register.html") 
    public void registerForm(@ModelAttribute RegisterCommand registerCommand) { 
     // no op 
    } 

    @RequestMapping(method = RequestMethod.POST, value = "/register.html") 
    public String registerNewUser(@ModelAttribute RegisterCommand command, 
      Errors errors) { 
     String returnView = "redirect:index.html"; 

     if (errors.hasErrors()) { 
      returnView = "register"; 
     } else { 
      User newUser = new User(); 
      newUser.setUsername(command.getUsername()); 
      newUser.setPassword(passwordEncoder.encodePassword(command 
        .getPassword(), null)); 
      newUser.setEmailAddress(command.getEmailAddress()); 
      newUser.setFirstName(command.getFirstName()); 
      newUser.setLastName(command.getLastName()); 

      userService.registerNewUser(newUser); 
     } 
     return returnView; 

    } 

    public Validator getValidator() { 
     return registrationValidator; 
    } 
} 
+0

Я должен добавьте, что контроллеры зарегистрированы в моей конфигурации контекста весны: <контекст: компонент-сканирование base-package = "com.shaneleopard.web" /> и использование DefaultAnnotationHandlerMapping и AnnotationMethodHa ndlerAdapter – layne 2008-09-29 23:23:35

ответ

0

Я думаю, вы обнаружите, что проблема связана с наследованием и с помощью аннотаций, они не хорошо перемешать.

Вы пытались реализовать вышеприведенное использование наследования и SimpleFormController со всеми остальными сведениями, настроенными в контексте вашего приложения? Это, по крайней мере, уменьшит проблему до аннотаций и вопросов наследования.

3

Layne, вы описали проблему, как происходит, когда ваш класс контроллер реализует интерфейс, но в примере кода вы указали, что проблема возникает, когда класс контроллера расширяет другой класс, ваша ValidatingController.

Возможно, родительский класс также определяет некоторые аннотации Spring, а контейнер Spring заметил их первым и классифицировал класс контроллера как этот тип управляемого объекта и не потрудился проверить аннотацию @Controller, которую вы также определили в подклассе. Просто догадайтесь, но если это произойдет, я предлагаю сообщить об этом команде Spring, поскольку это звучит как ошибка.

0

По умолчанию JDK прокси создаются с помощью интерфейса и, если контроллер реализует интерфейс который RequestMapping аннотацию игнорируется как targetClass не используется

Добавить это в сервлет контексте конфигурации:

<aop:aspectj-autoproxy proxy-target-class="true"/> 
Смежные вопросы