具有error handling的Spring MVC Rest服务控制器正确完成了吗?

我想知道如何正确实现一个应该作为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"; } } 

或者更确切地说:

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

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

您还可以使用Rest Controller中的@ExceptionHandler注释方法捕获exception。

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

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

首先,我认为在返回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服务时非常重要的部分。

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

你可以使用@ExceptionHandler@ControllerAdvice检查这个链接

使用ResponseEntity类来利用http状态代码的错误。

您可以尝试以下代码:

 @RequestMapping(value = "/profile", method = RequestMethod.GET) @ResponseBody @ResponseStatus(value = HttpStatus.OK) public ResponseEntity getUserProfile() { string userName = getUserAuthentication().getName(); if (StringUtils.isEmpty(userName)) RestUtil.defaultJsonResponse(""); User user = userService.getUserByUserNameWithCounters(userName); return RestUtil.getJsonResponse(new UserVO(user)); } 

如果你希望你的整个Exception with stackTrace传递给你的客户端,就像@Bart说你应该发送一个“ErrorResource”对象。

图书馆有现成的:

  com.github.zg2pro spring-rest-basis 0.2  

将它添加到您的项目中,然后只需在您的bean中添加一个“@ControllerAdvice”类,如项目wiki中所述 。

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