Rectangle 27 1

java How to handle RESTful delete in Spring MVC?


if (!wasOk) {
        throw new DataAccessException("Unable to delete item: " + item);
    }
@ExceptionHandler(DataAccessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleDataAccessException(DataAccessException ex) {
    // Do some stuff
    return "errorView";
}
@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";
}

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

And then have an annotated error handler in the same class

If you the issues with a delete can be fixed by the user, then this seems ok. If there is nothing the user can do then perhaps an error code status would be more correct. The only failure I can imagine for a deletion would be an authorization failure, which would be a 401. This could be set by adding a parameter to your method 'HttpServletResponse response'. Your code would become something like:

OK but when I do it like that, how do I put stuff in model to be available on page resolved as "errorView" ? Before I throw exception I put "model.addAttribute("badItem", item)" ... but it ain't available at errorView.jsp page

You can substitue other status codes as appropriate, but that is the General idea.

You could return a new ModelAndView("errorView", "badItem", ex.getItem()) from the controller, assuming you had a custom exception that could keep a reference to the item. Although that does seem a bit messy.

Note
Rectangle 27 1

java How to handle RESTful delete in Spring MVC?


@ResponseStatus(value = HttpStatus.NO_CONTENT)
HandlerExceptionResolver

It is the other way around. The client sends the id of the resource ,items/{id}, that it intends to delete, see my update.

Okay let's say I want to use HTTP405 since resource cannot be deleted. How do I tell user which entity couldn't be deleted? Can I simply put it in the Model and than on JSP page try if there is such property in model?

You should consider to use HTTP status codes to indicate whether or not the delete operation succeeds rather than redirects. For example HTTP 200 OK (or HTTP 204 No Content) to indicate that the operation was successful, and HTTP 404 Not Found if the resource you are trying to access does not exist, HTTP 405 Method Not Allowed if the delete operation is not allowed, etc. Based on the response status, the client can decide whether or not to keep the referenced resource (in your case the object that is referenced by item/{id} ).

Note
Rectangle 27 1

java How to handle RESTful delete in Spring MVC?


if (!wasOk) {
        throw new DataAccessException("Unable to delete item: " + item);
    }
@ExceptionHandler(DataAccessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleDataAccessException(DataAccessException ex) {
    // Do some stuff
    return "errorView";
}
@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";
}

And then have an annotated error handler in the same class

If you the issues with a delete can be fixed by the user, then this seems ok. If there is nothing the user can do then perhaps an error code status would be more correct. The only failure I can imagine for a deletion would be an authorization failure, which would be a 401. This could be set by adding a parameter to your method 'HttpServletResponse response'. Your code would become something like:

OK but when I do it like that, how do I put stuff in model to be available on page resolved as "errorView" ? Before I throw exception I put "model.addAttribute("badItem", item)" ... but it ain't available at errorView.jsp page

You can substitue other status codes as appropriate, but that is the General idea.

You could return a new ModelAndView("errorView", "badItem", ex.getItem()) from the controller, assuming you had a custom exception that could keep a reference to the item. Although that does seem a bit messy.

Note