具有错误处理的Spring MVC Rest服务控制器正确完成了吗?

pas*_*oop 25 java rest spring spring-mvc

我想知道如何正确实现一个应该作为REST服务的Spring Controller.特别是我想尝试使界面尽可能的RESTful.此外,我想使用HTTP错误代码,以便我的客户端可以采取相应的行动.

我想知道如何实现我的方法,所以他们返回JSON,如果一切正常(在响应的主体中)或抛出一个http错误代码以及一个自定义原因它没有工作(可能是来自DAO的错误或数据库).但是我不确定哪一个是正确的方法?返回一个String并添加值以返回Model,或者返回一个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";
    }
}
Run Code Online (Sandbox Code Playgroud)

或者更确切地说:

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我意识到代码不是"恰到好处",但我无法弄清楚如何使它成为需要的方式.也许一些经验回复会有所帮助?谢谢你的支持

mar*_*eig 30

您还可以@ExceptionHandler在Rest Controller中使用带注释的方法捕获异常.

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

这将使您的实际控制器/业务逻辑更清洁.

  • 我发现它看起来更干净如果我只有一个每个控制器的异常处理程序方法而不是它们的整个数组然后负责检查在这个处理程序中抛出了哪个错误 (2认同)

Bar*_*art 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

资源被序列化,结果将是

{"status":500, "message":"Yay!"}
Run Code Online (Sandbox Code Playgroud)

使用一个Map将工作,但我建议你写一些资源类,定义要返回的对象.它们更容易维护.Maps不提供任何结构,而结构是创建REST服务时非常重要的部分.

我不认为您应该返回嵌入了原始异常消息的资源.它可能泄漏您不希望任何人看到的信息.


Bas*_*hdy 8

你可以用@ExceptionHandler@ControllerAdvice检查此链接