In my Spring MVC webapp I have a generic RESTful controller for CRUD operations. And each concrete controller had to declare only a @RequestMapping
, for example /foo
. Generic controller handled all request to /foo
and /foo/{id}
.
But now I need to write a bit more complex CRUD controller which will get additional request params or path variables, e.g /foo/{date}
and /foo/{id}/{date}
. So I extend my generic CRUD controller and write overloaded fetch(id, date)
method which will deal with both {id}
and {date}
. That is not a problem.
But I also need to 'disable' fetch(id)
implementation derived from base class (resource mustn't be available at /foo/{id}
anymore, only at /foo/{id}/{date}
). The only idea I came up with is to override this method in my concrete controller, to map it on a fake uri and return null
. But this looks like rather ugly dirty hack because we expose some fake resource uri, instead of disabling it. May be there is a better practice?
Any ideas?
//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) { .... }
}