Spring MVC的REST服务控制器错误处理得当?(Spring MVC Rest Servic

2019-09-01 11:30发布

我不知道如何正确地执行它应该作为一个REST服务春季控制器。 特别是我想尝试使界面尽可能宁静。 此外,我想利用HTTP错误代码,所以我的客户可以采取相应的行动。

我不知道如何实现我的方法,让他们返回JSON如果一切正常(在响应主体)或抛出一个HTTP错误代码以及自定义的原因,它没有工作(也许从DAO来了错误或数据库)。 但是我不知道哪一个才是正确的方式? 返回一个字符串,并添加值恢复到模型,或返回一个HashMap,把我的东西在里面? 或者直接返回的对象? 但随后如果错误occures和我不能回说类? 返回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对于已经支持

Answer 1:

你也可以用你赶上例外@ExceptionHandler你的休息控制器内注释methos。

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

这会让你的acutal控制器/业务逻辑的清洁剂。



Answer 2:

首先,我想返回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将工作,但我想提醒你写它定义了对象返回一些资源类。 他们会更容易维护。 Maps而结构是非常重要的一部分来创建REST服务时不提供任何结构。

我不认为你应该返回一个资源嵌入原始异常消息。 它有可能泄露你不希望任何人看到的信息。



Answer 3:

您可以使用@ExceptionHandler@ControllerAdvice检查此链接



Answer 4:

使用ResponseEntity类利用与HTTP状态代码错误。

你可以尝试下面的代码:

@RequestMapping(value = "/profile", method = RequestMethod.GET) 
@ResponseBody @ResponseStatus(value = HttpStatus.OK) 

public ResponseEntity<UserVO> getUserProfile() 
{ 
   string userName = getUserAuthentication().getName(); 
   if (StringUtils.isEmpty(userName)) RestUtil.defaultJsonResponse(""); 
   User user = userService.getUserByUserNameWithCounters(userName); 
   return RestUtil.getJsonResponse(new UserVO(user)); 
}


Answer 5:

如果你希望你与堆栈跟踪整个异常向客户传送,如@Bart说你应该发送“ErrorResource”对象。

库有它关闭的,现成的:

<dependency>
  <groupId>com.github.zg2pro</groupId>
  <artifactId>spring-rest-basis</artifactId>
  <version>0.2</version>
</dependency>

它添加到您的项目,然后只需添加一个“@ControllerAdvice”类的豆,因为它是在解释项目wiki 。

这应该很好地处理你的错误!



文章来源: Spring MVC Rest Service Controller with Error Handling done right?