2012-04-26 28 views
7

Làm cách nào để sử dụng đúng cách xóa RESTful trong bộ điều khiển Spring MVC? Tôi có DAO trả về boolean khi cố gắng xóa một số mục.Làm thế nào để xử lý xóa RESTful trong Spring MVC

Tôi đang cố xóa mục. Nếu mọi thứ đều OK, chỉ hiển thị danh sách các mục (mục đã xóa sẽ không còn ở đó nữa). Nếu không thể xóa mục, hãy chuyển hướng đến trang chi tiết và nói lý do không thể xóa mục đó.

Tôi có cần một số trạng thái phản hồi đặc biệt hoặc một cái gì đó như thế này không? Cách tiếp cận của tôi là 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"; 
} 

Trả lời

10

Nếu bạn khắc phục sự cố với người dùng thì điều này có vẻ ổn. Nếu không có gì người dùng có thể làm thì có lẽ tình trạng mã lỗi sẽ chính xác hơn. Lỗi duy nhất tôi có thể tưởng tượng để xóa sẽ là một sự thất bại ủy quyền, đó sẽ là 401. Điều này có thể được thiết lập bằng cách thêm một tham số vào phương thức trả lời HttpServletResponse của phương thức của bạn. Mã của bạn sẽ trở thành một cái gì đó như:

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

Bạn có thể thay thế các mã trạng thái khác nếu thích hợp, nhưng đó là ý tưởng chung.

Bạn cũng có thể làm điều gì đó như:

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

Và sau đó có một xử lý lỗi chú thích trong cùng một lớp

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

OK nhưng khi tôi làm như vậy, làm cách nào để đưa nội dung vào mô hình có sẵn trên trang được giải quyết là "errorView"? Trước khi tôi ném ngoại lệ, tôi đặt "model.addAttribute (" badItem ", item)" ... nhưng nó không có sẵn tại trang errorView.jsp – Xorty

+0

Bạn có thể trả về một new ModelAndView ("errorView", "badItem", ví dụ .getItem()) 'từ bộ điều khiển, giả sử bạn có một ngoại lệ tùy chỉnh có thể giữ một tham chiếu đến mục đó. Mặc dù điều đó có vẻ hơi lộn xộn một chút. – Kodi

+0

Có lẽ đó là điều tốt nhất để làm – Xorty

15

Bạn nên cân nhắc sử dụng HTTP status codes để cho biết hoạt động xóa có thành công thay vì chuyển hướng hay không. Ví dụ: HTTP 200 OK (hoặc HTTP 204 No Content) để cho biết rằng thao tác thành công và HTTP 404 Not Found nếu tài nguyên bạn đang cố gắng truy cập không tồn tại, HTTP 405 Method Not Allowed nếu thao tác xóa không được phép, v.v. Dựa trên trạng thái phản hồi, khách hàng có thể quyết định có hay không giữ tài nguyên được tham chiếu (trong trường hợp của bạn đối tượng được tham chiếu bởi item/{id}).

Vì bạn đang sử dụng Spring, bạn có thể chú thích các phương pháp điều khiển của mình bằng @ResponseStatus thích hợp, ví dụ: @ResponseStatus(value = HttpStatus.NO_CONTENT)

Ngoài ra, Spring HandlerExceptionResolver đã cung cấp một số mã trạng thái theo default.

+0

Được rồi chúng ta hãy nói rằng tôi muốn sử dụng HTTP405 từ tài nguyên không thể bị xóa. Làm cách nào để tôi cho người dùng biết thực thể nào không thể bị xóa? Tôi có thể chỉ cần đặt nó trong trang Mô hình và hơn trên JSP thử nếu có thuộc tính như vậy trong mô hình? – Xorty

+0

Đó là một cách khác. * Client * gửi id của tài nguyên, 'items/{id}', mà nó dự định xóa, xem cập nhật của tôi. – matsev

Các vấn đề liên quan