Spring mvc 控制器扩展接口时无法识别带注释的Spring MVC控制器

Spring mvc 控制器扩展接口时无法识别带注释的Spring MVC控制器,spring-mvc,mapping,controller,annotations,Spring Mvc,Mapping,Controller,Annotations,我正在使用Spring2.5,并且正在使用注释来配置我的控制器。如果我没有实现任何附加接口,那么我的控制器可以正常工作,但是当我添加接口实现时,spring容器无法识别控制器/请求映射 我不明白为什么添加接口实现会弄乱控制器的配置和请求映射。有什么想法吗 因此,这是可行的: package com.shaneleopard.web.controller; import org.springframework.beans.factory.annotation.Autowired; import

我正在使用Spring2.5,并且正在使用注释来配置我的控制器。如果我没有实现任何附加接口,那么我的控制器可以正常工作,但是当我添加接口实现时,spring容器无法识别控制器/请求映射

我不明白为什么添加接口实现会弄乱控制器的配置和请求映射。有什么想法吗

因此,这是可行的:

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

我认为您会发现问题在于继承和使用注释,它们不能很好地混合

您是否尝试过使用继承和SimpleFormController以及在应用程序上下文中配置的所有其他详细信息来实现上述功能?这至少会将问题缩小到注释和继承问题。

layne,您将问题描述为控制器类实现接口时发生的问题,但在您提供的代码示例中,当控制器类扩展您的另一个类时,问题就会出现,
ValidatingController


也许父类还定义了一些Spring注释,Spring容器首先注意到了这些注释,并将controller类归类为该类型的托管对象,而没有检查您在子类中也定义了
@controller
注释。只是一个猜测,但如果结果属实,我建议将其报告给Spring团队,因为这听起来像是一个bug。

默认情况下,JDK代理是使用接口创建的,如果controller实现了一个接口,则RequestMapping注释将被忽略,因为targetClass未被使用

在servlet上下文配置中添加以下内容:

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


我应该补充一点,在我的spring上下文配置中,控制器是向以下对象注册的:并且使用DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter看起来不像是在导入ValidatingController-什么是完全限定的类名?我正在导入它。它与上面的控制器示例位于同一个包中。当我扩展ValidatingController基类时,我应该添加上面的代码,但是当我将ValidatingController编码为接口并让RegistrationController实现它时,它就会崩溃。