Spring-MVC 在控制器上使用@Controller实现接口的问题

2022-09-01 06:04:59

我正在使用spring 2.5和注释来配置我的spring-mvc Web上下文。不幸的是,我无法让以下内容发挥作用。我不确定这是否是一个错误(似乎就是这样),或者对注释和接口实现子类化的工作原理是否存在基本的误解。

例如

@Controller
@RequestMapping("url-mapping-here")
public class Foo {
  @RequestMapping(method=RequestMethod.GET)
  public void showForm() {
    ...
  }
  @RequestMapping(method=RequestMethod.POST)
  public String processForm() {
  ...
  }
}

工作正常。当上下文启动时,此处理程序处理的 URL 将被发现,并且一切正常。

但是,这不会:

@Controller
@RequestMapping("url-mapping-here")
public class Foo implements Bar {
  @RequestMapping(method=RequestMethod.GET)
  public void showForm() {
    ...
  }
  @RequestMapping(method=RequestMethod.POST)
  public String processForm() {
  ...
  }
}

当我尝试拉出URL时,我得到以下令人讨厌的堆栈跟踪:

javax.servlet.ServletException: No adapter for handler [com.shaneleopard.web.controller.RegistrationController@e973e3]: Does your handler implement a supported interface like Controller?
    org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter(DispatcherServlet.java:1091)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:874)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:627)

但是,如果我将Bar更改为抽象超类并让Foo扩展它,那么它就可以再次工作。

@Controller
@RequestMapping("url-mapping-here")
public class Foo extends Bar {
  @RequestMapping(method=RequestMethod.GET)
  public void showForm() {
    ...
  }
  @RequestMapping(method=RequestMethod.POST)
  public String processForm() {
  ...
  }
}

这似乎是一个错误。@Controller注释应该足以将其标记为控制器,并且我应该能够在控制器中实现一个或多个接口,而无需执行任何其他操作。有什么想法吗?


答案 1

我需要做的是更换

 <tx:annotation-driven/>

 <tx:annotation-driven  proxy-target-class="true"/>

这迫使 aspectj 使用 CGLIB 来执行方面而不是动态代理 - CGLIB 不会丢失注释,因为它扩展了类,而动态代理只是公开了实现的接口。


答案 2

艾德是对的,添加

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

工作正常