【问题标题】:Is it good practice to throw exception from DAO layer to controller?从 DAO 层向控制器抛出异常是一种好习惯吗?
【发布时间】:2015-03-18 05:35:28
【问题描述】:

我正在编写一个 REST api。我的 DAO 层可能有两个例外,即Exception_XException_Y。如果我在 DAO 层遇到异常Exception_X,我的控制器应该返回状态码200,如果是Exception_Y,则返回401,如果一切顺利,控制器应该返回201。 现在我在想我会抛出遇到的异常,因为它是通过服务层从 DAO 层到控制器,并且在控制器的 catch 块中,我将返回响应。 可以接受还是有其他标准方式?

【问题讨论】:

  • 是的,你可以这样做。你的方法没有问题。
  • 是的,你可以,最好创建自己的异常类并根据异常构造它们并抛出它们。
  • 没有标准的方法,我看到很多是的。但在我看来:将状态代码留在处理它们的地方,在你的控制器上。关注点分离的东西..

标签: java spring rest spring-mvc


【解决方案1】:

是的,这是一种完全可以接受的方式。但是,我建议不要使用try-catch,而是为您的 REST 控制器实现异常处理程序。这样,您就不必弄乱您的 REST 方法。

另外,最好在 REST 层为错误消息创建一个模型对象 - ErrorResponse,并提供适当的信息:

class ErrorResponse {
    int statusCode;
    String errorMessage;
}

并从异常处理程序返回它的对象。顺便说一句,您还可以使用 @ResponseStatus 注释将您的异常类直接映射到响应:

@ResponseStatus(value=401, reason="message")
class Exception_Y extends RuntimeException {
} 

那么您不必为该异常编写异常处理程序。

【讨论】:

    【解决方案2】:

    我的建议是使用服务层包装任何未经检查的异常,以实现松散耦合和干净的抽象。让您的控制器不受任何条件的影响,让服务层处理这种痛苦。

    牢记安全问题,如果你将它暴露在外部,用面向服务的异常包装你的异常,它也有助于实现通用的特定于层的异常,比如 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
    }
    

    【讨论】:

      【解决方案3】:

      我建议您使用 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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-22
        • 1970-01-01
        • 1970-01-01
        • 2015-05-22
        • 2016-06-09
        • 1970-01-01
        • 2015-09-02
        • 1970-01-01
        相关资源
        最近更新 更多