35

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 つ以上のインターフェースを実装できるはずです。何か案は?

4

6 に答える 6

13

私がする必要があったのは交換することでした

 <tx:annotation-driven/>

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

これにより、aspectj はダイナミック プロキシの代わりにアスペクトを実行するために CGLIB を使用するようになります。CGLIB はクラスを拡張するためアノテーションを失いませんが、ダイナミック プロキシは実装されたインターフェイスを公開するだけです。

于 2010-07-06T22:13:48.593 に答える
5

注釈と継承が少しトリッキーになることは間違いありませんが、うまくいくはずだと思います。AnnotationMethodHandlerAdapter をサーブレット コンテキストに明示的に追加してみてください。

http://static.springframework.org/spring/docs/2.5.x/reference/mvc.html#mvc-ann-setup

それでもうまくいかない場合は、もう少し情報が役立ちます。具体的には、インターフェイスからの 2 つの注釈付きコントローラー メソッドですか? Foo は RegistrationController であるはずですか?

于 2008-12-10T06:22:49.837 に答える
0

'proxy-target-class="true"' を使用する必要がある本当の理由はDefaultAnnotationHandlerMapping#determineUrlsForHandler()メソッドにあります: 注釈を検索するために使用ListableBeanFactory#findAnnotationOnBean@RequestMappingますが (これによりプロキシの問題が処理されます)、@Controller注釈の追加の検索はAnnotationUtils#findAnnotation(これはプロキシの問題を処理しません)

于 2010-09-05T08:46:25.840 に答える