15

私のSpringMVCWebアプリには、CRUD操作用の汎用RESTfulコントローラーがあります。@RequestMappingそして、各具象コントローラーは、たとえば、のみを宣言する必要がありました/foo/foo汎用コントローラーは、およびへのすべての要求を処理しまし/foo/{id}た。

/foo/{date}しかし、今度は、追加のリクエストパラメータまたはパス変数(例:および)を取得する、もう少し複雑なCRUDコントローラーを作成する必要があり/foo/{id}/{date}ます。そこで、汎用のCRUDコントローラーを拡張し、fetch(id, date)との両方を処理するオーバーロードされたメソッドを{id}記述し{date}ます。それは問題ではない。

fetch(id)ただし、基本クラスから派生した実装を「無効にする」必要もあり ます(リソースは/foo/{id}、でのみ使用可能にする必要があります/foo/{id}/{date})。私が思いついた唯一のアイデアは、具象コントローラーでこのメソッドをオーバーライドし、偽のURIにマップして、を返すことnullです。しかし、これは、無効にするのではなく、偽のリソースURIを公開しているため、かなり醜い汚いハックのように見えます。より良い習慣があるのでしょうか?

何か案は?

//My generic CRUD controller
public abstract class AbstractCRUDControllerBean<E, PK extends Serializable> implements AbstractCRUDController<E, PK> {

  @RequestMapping(method=RequestMethod.GET)
  public @ResponseBody ResponseEntity<E[]> fetchAll() { ... }

  @RequestMapping(value="/{id}", method=RequestMethod.GET)
  public @ResponseBody ResponseEntity<E> fetch(@PathVariable("id") PK id) { ... }

  @RequestMapping(method=RequestMethod.POST)
  public @ResponseBody ResponseEntity<E> add(@RequestBody E entity) { ... }

  @RequestMapping(value="/{id}", method=RequestMethod.PUT)
  public @ResponseBody ResponseEntity<E> update(@PathVariable("id") PK id, @RequestBody E entity) { ... }

  @RequestMapping(value="/{id}", method=RequestMethod.DELETE)
  public @ResponseBody ResponseEntity<E> remove(@PathVariable("id") PK id) { .. }
} 

//Concrete controller, working with Foo entities
@Controller
@RequestMapping("/foo")
public class FooControllerImpl extends
        AbstractCRUDControllerBean<Foo, Long> implements FooController { 

  //ugly overriding parent's method
  @RequestMapping(value="/null",method=RequestMethod.GET)
  public @ResponseBody ResponseEntity<Foo> fetch(@PathVariable("id") PK id) { 
    return null;
  }

  //new fetch implementation
  @RequestMapping(value="/{id}/{date}", method=RequestMethod.GET)
  public @ResponseBody ResponseEntity<Foo> fetch(@PathVariable("id") PK id, @PathVariable("date") Date date) { .... }

}
4

1 に答える 1

19

春を利用して、リソース、サブリソースタイプのジャージを実現しようとしていますか?それは直接不可能かもしれません。汎用のRESTfulサービスをコントローラーとして宣言する代わりに、それらに委任してみませんか?

//My generic CRUD Operations
public abstract class AbstractCRUDControllerBean<E, PK extends Serializable> implements AbstractCRUDController<E, PK> {

  public ResponseEntity<E[]> fetchAll() { ... }

  public ResponseEntity<E> fetch(@PathVariable("id") PK id) { ... }

  public ResponseEntity<E> add(@RequestBody E entity) { ... }

  public ResponseEntity<E> update(@PathVariable("id") PK id, @RequestBody E entity) { ... }

  public ResponseEntity<E> remove(@PathVariable("id") PK id) { .. }
} 

コントローラで委任します。

//Concrete controller, working with Foo entities
@Controller
@RequestMapping("/foo")
public class FooControllerImpl extends
        AbstractCRUDControllerBean<Foo, Long> implements FooController { 

  //we are interested in using fetchall but not others
  @RequestMapping(method=RequestMethod.GET)
  public @ResponseBody ResponseEntity<Foo> fetch(@PathVariable("id") PK id) { 
    return fetchAll();
  }

  //fetch with id and date
  @RequestMapping(value="/{id}/{date}", method=RequestMethod.GET)
  public @ResponseBody ResponseEntity<Foo> fetch(@PathVariable("id") PK id, @PathVariable("date") Date date) { .... }

}

また、パラメータの可用性に基づいてメソッドをマッピングすることもできます。

@RequestMapping(value="/{id}/{date}", params={"param1","param2","!param3"})
public @ResponseBody ResponseEntity<E> customFetch(@PathVariable("id") PK id, 
            @PathVariable("date") Date date, @RequestParam("param1") String param1,                
            @RequestParam("param2") String param2) {...}

このメソッドは、param1とparam2が存在し、param3が存在しない場合に/ foo / id/dateをマップします。

于 2011-09-12T17:53:07.663 に答える