2012-04-26 17 views
7

¿Cómo uso correctamente la eliminación RESTful en el controlador Spring MVC? Tengo DAO que devuelve boolean cuando intento eliminar algún elemento.Cómo manejar la eliminación RESTful en Spring MVC

Estoy tratando de eliminar el artículo. Si todo estaba bien, solo muestra la lista de elementos (el elemento eliminado ya no estará allí). Si el elemento no se puede eliminar, redirija a la página de detalles y diga por qué no se pudo eliminar.

¿Necesito algún tipo de respuesta especial o algo como esto? ¿Mi enfoque es RESTful?

@RequestMapping(value = "items/{id}", method = RequestMethod.DELETE) 
public String delete(@PathVariable("id") int itemId, Model model) { 
    Item item = itemDao.get(id); 

    // true -> can delete 
    // false -> cannot delete, f.e. is FK reference somewhere 
    boolean wasOk = itemDao.delete(item); 

    if (wasOk) { 
     return "redirect:/items"; 
    } 

    // will write to user which item couldn't be deleted 
    model.addAttribute("item", item); 
    return "items/error"; 
} 

Respuesta

10

Si el usuario puede resolver los problemas con una eliminación, entonces esto parece correcto. Si no hay nada que el usuario pueda hacer, tal vez un código de error sea más correcto. La única falla que puedo imaginar para una eliminación sería un error de autorización, que sería un 401. Esto podría establecerse agregando un parámetro a su método 'HttpServletResponse response'. Su código se convertiría en algo como:

@RequestMapping(value = "items/{id}", method = RequestMethod.DELETE) 
public String delete(@PathVariable("id") int itemId, Model model, HttpServletReponse response) { 
    Item item = itemDao.get(id); 

    // true -> can delete 
    // false -> cannot delete, f.e. is FK reference somewhere 
    boolean wasOk = itemDao.delete(item); 

    if (!wasOk) { 
     // will write to user which item couldn't be deleted 
     response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
     model.addAttribute("item", item); 
     return "items/error"; 
    } 

    return "redirect:/items"; 
} 

Puede substitue otros códigos de estado según el caso, pero esa es la idea general.

También podría hacer algo como:

if (!wasOk) { 
     throw new DataAccessException("Unable to delete item: " + item); 
    } 

Y luego tener un controlador de errores anotada en la misma clase

@ExceptionHandler(DataAccessException.class) 
@ResponseStatus(HttpStatus.BAD_REQUEST) 
public String handleDataAccessException(DataAccessException ex) { 
    // Do some stuff 
    return "errorView"; 
} 
+0

OK, pero cuando lo hago así, ¿cómo pongo cosas en el modelo para que estén disponibles en la página resuelta como "errorView"? Antes de lanzar la excepción, coloque "model.addAttribute (" badItem ", artículo)" ... pero no está disponible en la página errorView.jsp – Xorty

+0

Puede devolver un 'new ModelAndView (" errorView "," badItem ", ex .getItem()) 'del controlador, suponiendo que haya una excepción personalizada que pueda mantener una referencia al elemento. Aunque eso parece un poco complicado. – Kodi

+0

Ye eso es probablemente lo mejor para hacer cajero automático – Xorty

15

Debe tener en cuenta al utilizar HTTP status codes para indicar si o no tiene éxito la operación de eliminación en lugar de redirecciones. Por ejemplo HTTP 200 OK (o HTTP 204 No Content) para indicar que la operación fue exitosa, y HTTP 404 Not Found si el recurso al que intenta acceder no existe, HTTP 405 Method Not Allowed si no se permite la operación de eliminación, etc. Según el estado de la respuesta, el cliente puede decidir si mantener o no el recurso al que se hace referencia (en su caso, el objeto al que hace referencia el item/{id}).

Dado que está utilizando Spring, puede anotar los métodos de su controlador con un @ResponseStatus apropiado, p. @ResponseStatus(value = HttpStatus.NO_CONTENT)

Además, Spring HandlerExceptionResolver ya proporciona algunos códigos de estado por default.

+0

bien digamos que quiero usar HTTP405 ya que los recursos no se puede eliminar. ¿Cómo le digo al usuario qué entidad no se pudo eliminar? ¿Puedo simplemente ponerlo en el Modelo y que en la página JSP probar si existe tal propiedad en el modelo? – Xorty

+0

Es al revés. El * cliente * envía la identificación del recurso, 'items/{id}', que intenta eliminar, vea mi actualización. – matsev

Cuestiones relacionadas