2012-04-26 12 views
7

Come faccio a utilizzare correttamente RESTful delete nel controller Spring MVC? Ho DAO che restituisce booleano quando si tenta di eliminare alcuni elementi.Come gestire l'eliminazione RESTful in Spring MVC

Sto tentando di eliminare l'elemento. Se tutto era OK, mostra solo l'elenco degli articoli (l'elemento cancellato non sarà più lì). Se l'articolo non può essere rimosso, reindirizza alla pagina dei dettagli e spiega perché non è stato possibile eliminarlo.

Ho bisogno di qualche stato di risposta speciale o qualcosa del genere? RESTful è il mio approccio?

@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"; 
} 

risposta

10

Se i problemi con una cancellazione possono essere risolti dall'utente, questo sembra ok. Se non c'è nulla che l'utente possa fare, forse lo stato di un codice di errore sarebbe più corretto. L'unico errore che posso immaginare per una cancellazione sarebbe un errore di autorizzazione, che sarebbe un 401. Questo potrebbe essere impostato aggiungendo un parametro al metodo 'HttpServletResponse response'. Il tuo codice diventerebbe qualcosa del tipo:

@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"; 
} 

È possibile sostituire altri codici di stato come appropriato, ma questa è l'idea generale.

Si potrebbe anche fare qualcosa di simile:

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

E poi avere un gestore di errori annotato nella stessa classe

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

OK ma quando lo faccio in questo modo, come faccio a mettere le cose nel modello per essere disponibili sulla pagina risolta come "errorView"? Prima di lanciare l'eccezione, ho inserito "model.addAttribute (" badItem ", elemento)" ... ma non è disponibile nella pagina errorView.jsp – Xorty

+0

È possibile restituire un 'nuovo ModelAndView (" errorView "," badItem ", ex .getItem()) 'dal controller, supponendo che tu abbia un'eccezione personalizzata che potrebbe mantenere un riferimento all'elemento. Anche se sembra un po 'complicato. – Kodi

+0

Sì, probabilmente è la cosa migliore da fare – Xorty

15

Si dovrebbe prendere in considerazione di utilizzare HTTP status codes per indicare se l'operazione di eliminazione riesce piuttosto che reindirizzamenti. Ad esempio HTTP 200 OK (o HTTP 204 No Content) per indicare che l'operazione ha avuto esito positivo e HTTP 404 Not Found se la risorsa a cui si sta tentando di accedere non esiste, HTTP 405 Method Not Allowed se l'operazione di eliminazione non è consentita, ecc. In base allo stato della risposta, il client può decidere se mantenere o meno la risorsa di riferimento (nel tuo caso l'oggetto a cui viene fatto riferimento da item/{id}).

Poiché si utilizza Spring, è possibile annotare i metodi del controller con uno @ResponseStatus appropriato, ad es. @ResponseStatus(value = HttpStatus.NO_CONTENT)

Inoltre, la primavera HandlerExceptionResolver fornisce già alcuni codici di stato da default.

+0

Va bene diciamo che voglio usare HTTP405 in quanto risorsa non può essere eliminata. Come posso dire all'utente quale entità non può essere cancellata? Posso semplicemente inserirmi nel modello e nella pagina JSP provare se esiste una tale proprietà nel modello? – Xorty

+0

È il contrario. Il * client * invia l'id della risorsa, 'items/{id}', che intende eliminare, vedere il mio aggiornamento. – matsev

Problemi correlati