2009-12-29 3 views
1

Je rencontre un problème étrange avec les contrôleurs annotés et Spring MVC. J'essayais d'utiliser des contrôleurs annotés pour l'exemple d'application MVC que Spring livre avec sa documentation. J'ai utilisé la version 2.5.Problème de contrôleur MVC et de contrôleurs annotés:

Quand je précise @RequestMapping au niveau du type, je reçois « ERREUR HTTP: 500 Aucun adaptateur pour gestionnaire [nom de classe Controller]: Est-ce que votre gestionnaire implémentent une interface pris en charge comme contrôleur

Si je l'inclure dans? le niveau de la méthode, il fonctionne très bien avec à un problème Ajout ou suppression des adaptateurs de poignée par défaut pour les fichiers de contexte fait aucune différence.

Enfin, j'ai eu recours à avoir @RequestMapping au niveau du contrôleur, ainsi que un au niveau de la méthode, et il travaillé. Quelqu'un sait quel pourrait être le problème?

Voici l'exemple de code:

Cela ne fonctionne pas:

@Controller 
@RequestMapping("/*") 
public class InventoryController { 
    protected final Log logger = LogFactory.getLog(getClass()); 

    @Autowired 
    private ProductManager productManager; 


    public ModelAndView inventoryHandler() { 
     String now = (new java.util.Date()).toString(); 
     logger.info("returning hello view with " + now); 
     Map<String, Object> myModel = new HashMap<String, Object>(); 
     myModel.put("now", now); 
     myModel.put("products", this.productManager.getProducts()); 
     return new ModelAndView("hello", "model", myModel); 
    } 
} 

Cela a fonctionné:

@Controller 

public class InventoryController { 
    protected final Log logger = LogFactory.getLog(getClass()); 

    @Autowired 
    private ProductManager productManager; 

    @RequestMapping("/hello.htm") 
    public ModelAndView inventoryHandler() { 
     String now = (new java.util.Date()).toString(); 
     logger.info("returning hello view with " + now); 
     Map<String, Object> myModel = new HashMap<String, Object>(); 
     myModel.put("now", now); 
     myModel.put("products", this.productManager.getProducts()); 
     return new ModelAndView("hello", "model", myModel); 
    } 
} 

Cela a également travaillé:

@Controller 
@RequestMapping("/*") 
public class InventoryController { 
    protected final Log logger = LogFactory.getLog(getClass()); 

    @Autowired 
    private ProductManager productManager; 

    @RequestMapping(method = RequestMethod.GET, value = "/hello.htm") 
    public ModelAndView inventoryHandler() { 
     String now = (new java.util.Date()).toString(); 
     logger.info("returning hello view with " + now); 
     Map<String, Object> myModel = new HashMap<String, Object>(); 
     myModel.put("now", now); 
     myModel.put("products", this.productManager.getProducts()); 
     return new ModelAndView("hello", "model", myModel); 
    } 
} 

Toutes les idées, Qu'est-ce qu'il se passe ici? J'ai fait beaucoup de recherche et pas de solution. J'ai aussi essayé avec 2.5.6, et le problème était similaire.

Répondre

7

Vous devez mettre @RequestMapping sur la méthode parce que le mettre sur la classe n'est pas assez d'informations - Spring doit savoir quelle méthode appeler pour gérer la demande.

Si votre classe ne dispose que d'une seule méthode, il est compréhensible que vous pensiez qu'elle choisirait cette méthode, mais ce n'est pas le cas. Considérons que l'un des avantages des contrôleurs annotés est que vous pouvez avoir autant de méthodes non associées @RequestMapping dans votre classe que vous le souhaitez.

+0

Merci. Je devenais vraiment fou à ce sujet. J'ai suivi l'idée de ce blog, je me demande comment cela a fonctionné pour l'auteur du blog: http://cchweblog.wordpress.com/2009/06/20/developing-spring-mvc-application-annotation-based-controller-and -jpa/ EDIT: Je comprends l'avantage de l'avoir sous chaque méthode. En fait, ce serait une bonne idée de le mettre même pour une seule méthode en classe, qui sait que je pourrais ajouter plus de méthodes plus tard! – Shaw

+0

Il a '@ RequestMapping' sur ses méthodes aussi. – skaffman

+0

Ah!Bonne prise .. J'ai vraiment manqué ça .. Je ne sais pas comment j'ai négligé .. Merci encore! – Shaw

1

C'est parce que la première configuration ne dit pas quelle méthode de la classe appelle.

3

Vous n'avez pas besoin d'utiliser @RequestMapping sur la classe. C'est juste une commodité. Vous avez besoin des annotations de niveau de méthode @RequestMapping.

Compte tenu de ceci:

@Controller 
public class InventoryController { 
... 
@RequestMapping("/inventory/create/{id}") 
public void create(...){} 

@RequestMapping("/inventory/delete/{id}") 
public void delete(...){} 
... 

Vous pouvez factoriser la partie de l'inventaire de l'URI.

@Controller 
@RequestMapping("/inventory") 
public class InventoryController { 
... 
@RequestMapping("create/{id}") 
public void create(...){} 

@RequestMapping("delete/{id}") 
public void delete(...){} 
... 
Questions connexes