25

REST サービスとして機能するはずの Spring Controller を正しく実装する方法を知りたいと思っていました。特にインターフェイスをできるだけ RESTful なものにしたいと思っています。また、クライアントがそれに応じて動作できるように、HTTP エラー コードを利用したいと考えています。

メソッドを実装する方法を考えていたので、(応答の本文で) すべてが正常に機能する場合は JSON を返すか、http エラー コードと、それが機能しなかったカスタムの理由 (DAO から発生したエラーまたはデータベース)。しかし、どちらが正しい方法なのかわかりませんか?文字列を返し、返される値をモデルに追加するか、HashMap を返し、そこに自分のものを入れますか? またはオブジェクトを直接返しますか?しかし、エラーが発生し、そのクラスを返すことができない場合はどうなりますか? 代わりに null を返しますか? 私が想像できる2〜3の方法を投稿します:

@RequestMapping(value="/addUser", method= RequestMethod.POST)
public String addUser(@RequestBody User user, HttpServletResponse response, Model model) throws Exception{

    try{
        userService.addUser(user);
        model.addAttribute("user", userService.getUser(user.getUsername(), user.getPassword()));
        return "user";
    }catch(Exception e){
        model.addAttribute("error", e.toString());
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString());
        return "error";
    }
}

またはむしろこのように:

@RequestMapping(value="/addUser", method= RequestMethod.POST)
public @ResponseBody Map addUser(@RequestBody User user, HttpServletResponse response){
    Map map = new HashMap();
    try{
        userService.addUser(user);
        map.put("success", true);
        map.put("username", user.getUsername());
    }catch (KeyAlreadyExistsException e){
        map.put("success", false);
        map.put("Error", e.toString());
        response.sendError(HttpServletResponse.SC_FORBIDDEN, e.toString());
    }catch(Exception e){
        map.put("success", false);
        map.put("Error", e.toString());
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString());
    }
    finally {
        return map;
    }
}

コードが「ちょうどいい」ものではないことはわかっていますが、必要な方法でコードを作成する方法がわかりません。たぶん、いくつかの経験の回答が役立つでしょうか?すでにサポートのためのThx

4

5 に答える 5

31

@ExceptionHandlerRest Controller 内の注釈付きメソッドで例外をキャッチすることもできます。

@ExceptionHandler(Exception.class)
@ResponseBody
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public String handleException(Exception e) {
    return "return error object instead";
}

これにより、実際のコントローラー/ビジネスロジックがよりクリーンになります。

于 2013-04-30T10:16:38.330 に答える
16

まず、JSON を返すときは常にオブジェクトを返す必要があると思います。何かがひどくうまくいかないときでさえ。

何か問題が発生した場合response.setStatus()は、エラーを説明するリソースを設定して返すだけです。

public class ErrorResource implements Resource {
    private final int status;
    private final String message;

    public ErrorResource(int s, String m) {
        status = s;
        message = m;
    }

    public int getStatus() {
        return status;
    }

    public String getMessage() {
        return message;
    }
}

リソースはシリアル化され、結果は次のようになります

{"status":500, "message":"Yay!"}

を使用してMapも機能しますが、返されるオブジェクトを定義するリソース クラスをいくつか作成することをお勧めします。彼らは維持するのがより簡単になるでしょう。MapsREST サービスを作成する場合、構造は非常に重要な部分ですが、構造を提供しないでください。

生の例外メッセージが埋め込まれたリソースを返す必要はないと思います。誰にも見られたくない情報が漏洩する可能性があります。

于 2013-04-30T08:40:45.803 に答える