11

Spring MVCコントローラーでRESTful削除を正しく使用するにはどうすればよいですか?いくつかのアイテムを削除しようとするとブール値を返すDAOがあります。

アイテムを削除しようとしています。すべて問題がなければ、アイテムのリストを表示するだけです(削除されたアイテムはもう表示されません)。アイテムを削除できない場合は、詳細ページにリダイレクトして、削除できなかった理由を説明してください。

特別な応答ステータスなどが必要ですか?私のアプローチは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";
}
4

2 に答える 2

19

リダイレクトではなく、削除操作が成功したかどうかを示すためにHTTPステータスコードを使用することを検討する必要があります。たとえば、HTTP 200 OK(またはHTTP 204 No Content)は、操作が成功したこと、HTTP 404 Not Foundアクセスしようとしているリソースが存在しないHTTP 405 Method Not Allowed場合、削除操作が許可されていない場合などを示します。クライアントは、応答ステータスに基づいて、参照されるリソース(この場合、によって参照されるオブジェクトitem/{id})を保持します。

Springを使用しているため、コントローラーメソッドに適切な@ResponseStatusアノテーションを 付けることができます。@ResponseStatus(value = HttpStatus.NO_CONTENT)

さらに、SpringはすでにデフォルトでHandlerExceptionResolverいくつかのステータスコードを提供しています。

于 2012-04-26T20:12:54.113 に答える
12

削除に関する問題をユーザーが修正できる場合、これは問題ないようです。ユーザーができることは何もない場合は、エラーコードのステータスの方が正しい可能性があります。削除について私が想像できる唯一の失敗は、承認の失敗であり、これは401になります。これは、メソッド「HttpServletResponseresponse」にパラメーターを追加することで設定できます。コードは次のようになります。

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

必要に応じて他のステータスコードに置き換えることができますが、それが一般的な考え方です。

次のようなこともできます。

    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";
}
于 2012-04-26T20:25:11.767 に答える