我正在编写一个REST API。我的DAO层可能有两个例外,Exception_X
和Exception_Y
。如果我在DAO层遇到异常Exception_X
,我的控制器应返回状态代码200
,如果Exception_Y
然后401
,如果一切顺利,控制器应返回201
}。
现在我认为我会抛出遇到的异常,因为它是从DAO层通过服务层到控制器而在控制器的catch
块中我将返回响应。
可接受还是有其他标准方式?
答案 0 :(得分:8)
是的,这是一种非常可接受的方式。但是,我建议不要使用try-catch
来为您的REST控制器实现异常处理程序。这样,您就不必混乱REST方法。
此外,最好在REST层中为错误消息创建模型对象 - ErrorResponse
,并提供适当的信息:
class ErrorResponse {
int statusCode;
String errorMessage;
}
从异常处理程序返回它的对象。顺便说一句,您还可以使用@ResponseStatus
注释将您的异常类直接映射到响应:
@ResponseStatus(value=401, reason="message")
class Exception_Y extends RuntimeException {
}
然后您不必为该异常编写异常处理程序。
答案 1 :(得分:1)
我的建议是将任何未经检查的异常与服务层一起包装,以实现松散耦合和干净的抽象。保持控制器免受条件限制,让服务层处理这种痛苦。
如果将外部暴露在外部包装面向服务的异常,请记住安全性问题,这也有助于实现通用的层特定异常说PersistentException,ServiceException等保持良好的解耦程度记住。
为了全局处理异常,您可以使用带有JsonExceptionModel的spring inbuild ControllerAdvice批注来格式化错误响应。
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(SQLException.class)
public Map<String, Object> handleSQLException(HttpServletRequest request, Exception ex) {
//json response here
}
}
public class JsonExceptionModel {
private int code;
private String type;
private String url;
private String message;
private String moreInfo;
// getters/setters here
}
答案 2 :(得分:0)
我建议您使用Spring提供的Exception Resolver。 Spring Framework提供了HandlerExceptionResolver接口,我们可以实现它来创建全局异常处理程序。我们还可以覆盖它以使用我们的应用程序特定更改创建自己的全局处理程序,例如记录异常消息。
以下是HandlerExceptionResolver的示例实现,它将满足您的需求
public class RestResponseStatusExceptionResolver extends HandlerExceptionResolver {
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
if (ex instanceof InvalidInputException) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return handleException(ex);
} else if (ex instanceof ResourceNotFoundException) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return handleException(ex);
}
//Adding error details to modelView object
modelAndView.addObject("errors", ErrorDetails);
// Custom error message details
public class ErrorDetails {
private String code;
private List<String> data;
}