2008-09-29 16 views
5

J'utilise spring 2.5 et j'utilise des annotations pour configurer mes contrôleurs. Mon contrôleur fonctionne correctement si je n'implémente aucune interface supplémentaire, mais le conteneur de ressort ne reconnaît pas le mappage contrôleur/requête lorsque j'ajoute des implémentations d'interface.Le contrôleur Spring-MVC annoté n'est pas reconnu lorsque le contrôleur étend l'interface

Je n'arrive pas à comprendre pourquoi l'ajout d'une implémentation d'interface remet en cause la configuration du contrôleur et les mappages de requêtes. Des idées?

Alors, cela fonctionne:

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

mais cela ne veut pas:

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

je devrais ajouter que les contrôleurs sont enregistrés avec les éléments suivants dans mon contexte de printemps config: et en utilisant le DefaultAnnotationHandlerMapping et AnnotationMethodHa ndlerAdapter – layne

+0

Il ne semble pas que vous importiez ValidatingController - quel est le nom de classe complet? –

+0

Je l'importe. C'est dans le même paquet que l'exemple de contrôleur ci-dessus. Je devrais ajouter le code ci-dessus fonctionne quand j'étend la classe de base ValidatingController, mais quand je code ValidatingController en tant qu'interface et que le RegistrationController l'implémente, alors il casse. – layne

Répondre

0

Je pense que vous constaterez que le problème est de faire avec l'héritage et à l'aide d'annotations, ils ne le font pas bien mélanger.

Avez-vous essayé de mettre en œuvre l'héritage ci-dessus et SimpleFormController avec tous les autres détails configurés dans votre contexte d'application? Cela réduira au moins le problème à un problème d'annotations et d'héritage.

3

Layne, vous avez décrit le problème qui se passe lorsque votre classe contrôleur implémente une interface, mais dans l'exemple de code que vous avez fourni, le problème se produit lorsque votre classe contrôleur étend une autre classe de la vôtre, ValidatingController. La classe parent définit peut-être également certaines annotations Spring, et le conteneur Spring les a remarquées en premier et a classé la classe de contrôleur en tant que ce type d'objet géré et n'a pas pris la peine de vérifier l'annotation @Controller que vous avez définie dans la sous-classe. Juste une conjecture, mais si cela se passe, je suggère de le signaler à l'équipe de printemps, car cela ressemble à un bug.

0

Par procuration JDK par défaut sont créés à l'aide interface et si le contrôleur implémente une interface l'annotation RequestMapping est ignorée comme targetClass n'est pas utilisé

Ajouter dans votre contexte servlet config:

<aop:aspectj-autoproxy proxy-target-class="true"/>