En mi aplicación web Spring MVC tengo un controlador RESTful genérico para operaciones CRUD. Y cada controlador concreto tenía que declarar solo un @RequestMapping
, por ejemplo /foo
. El controlador genérico manejó todas las solicitudes a /foo
y /foo/{id}
.Herencia y enrutamiento del controlador MVC de resorte
Pero ahora tengo que escribir un controlador CRUD un poco más complejo que obtendrá parámetros de solicitud adicionales o variables de ruta, por ejemplo, /foo/{date}
y /foo/{id}/{date}
. Así que extiendo mi controlador genérico CRUD y escribo sobrecargado el método fetch(id, date)
que tratará tanto con {id}
como con {date}
. Eso no es problema.
Pero también necesito 'desactivar' la implementación fetch(id)
derivada de la clase base (el recurso no debe estar disponible en /foo/{id}
, solo en /foo/{id}/{date}
). La única idea que se me ocurrió es anular este método en mi controlador concreto, mapearlo en un uri falso y devolver null
. Pero esto parece un hack sucio bastante feo porque exponemos algunos recursos uri falsos, en lugar de deshabilitarlos. ¿Puede haber una mejor práctica?
¿Alguna idea?
//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) { .... }
}
Gracias por esta idea. Se adapta muy bien a mis necesidades. A veces, cuando estás atascado, todo lo que necesitas es cambiar un punto de vista) – Nofate
+1 buena respuesta y bien explicada – andyb