2008-09-29 20 views
5

Ich benutze Spring 2.5 und verwende Anmerkungen, um meine Controller zu konfigurieren. Mein Controller funktioniert einwandfrei, wenn ich keine zusätzlichen Schnittstellen implementiere, aber der Spring-Container erkennt das Controller/Request-Mapping nicht, wenn ich Schnittstellenimplementierungen hinzufüge.Kommentierter Spring-MVC-Controller wird nicht erkannt, wenn der Controller die Schnittstelle erweitert

Ich kann nicht herausfinden, warum das Hinzufügen einer Schnittstellenimplementierung die Konfiguration des Controllers und die Anforderungszuordnungen durcheinander bringt. Irgendwelche Ideen?

Also, das funktioniert:

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

aber nicht:

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

ich sollte fügen Sie hinzu, dass Controller in meinem Frühjahr Kontext config registriert sind: und die Verwendung von DefaultAnnotationHandlerMapping und AnnotationMethodHa ndlerAdapter – layne

+0

Es sieht nicht so aus, als ob Sie den ValidatingController importieren - was ist der voll qualifizierte Klassenname? –

+0

Ich importiere es. Es befindet sich im selben Paket wie das obige Controller-Beispiel. Ich sollte hinzufügen, dass der obige Code funktioniert, wenn ich die ValidatingController-Basisklasse erweitere, aber wenn ich ValidatingController als Schnittstelle codiere und RegistrationController es implementiere, dann bricht es ab. – layne

Antwort

0

Ich glaube, Sie werden feststellen, dass das Problem mit dem Erbe und mit Anmerkungen zu tun ist, tun sie nicht gut mischen.

Haben Sie versucht, das oben Genannte mit Vererbung und SimpleFormController mit allen anderen im Anwendungskontext konfigurierten Details zu implementieren? Dadurch wird das Problem zumindest auf ein Problem mit Anmerkungen und Vererbung beschränkt.

3

layne, beschrieben Sie das Problem so geschieht, wenn der Controller-Klasse implementiert eine Schnittstelle, sondern in dem Codebeispiel Sie zur Verfügung gestellt, das Problem tritt auf, wenn Ihr Controller-Klasse eine andere Klasse von Ihnen erstreckt, ValidatingController.

Möglicherweise definiert die übergeordnete Klasse auch einige Spring-Annotationen, und der Spring-Container hat sie zuerst bemerkt und die Controller-Klasse als diese Art von verwaltetem Objekt klassifiziert und nicht nach der @Controller Annotation gesucht, die Sie ebenfalls in der Unterklasse definiert haben. Nur eine Vermutung, aber wenn das herauskommt, würde ich vorschlagen, es dem Spring-Team zu melden, da es sich wie ein Käfer anhört.

0

standardmäßig JDK Proxy erstellt Schnittstelle und wenn die Steuerung über eine Schnittstelle die RequestMapping Anmerkung wird implementiert ignoriert wie die target

ist dies nicht in Ihrem Servletkontext Config hinzufügen verwendet:

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