【问题标题】:Annotated Spring-MVC controller not recognized when controller extends interface控制器扩展接口时无法识别带注释的 Spring-MVC 控制器
【发布时间】:2010-09-14 03:34:43
【问题描述】:

我正在使用 spring 2.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;
    }
}

【问题讨论】:

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

标签: spring-mvc mapping controller annotations


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    也许父类也定义了一些 Spring 注解,Spring 容器首先注意到它们并将控制器类归类为该类型的托管对象,并且没有费心检查您也在子类中定义的 @Controller 注解。只是一个猜测,但如果成功,我建议向 Spring 团队报告,因为这听起来像是一个错误。

    【讨论】:

      【解决方案3】:

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

      将此添加到您的 servlet 上下文配置中:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-21
        • 1970-01-01
        • 2010-12-30
        • 1970-01-01
        • 2018-03-13
        • 2018-11-11
        • 2015-01-15
        • 2011-03-09
        相关资源
        最近更新 更多