java - REST 服务的异常层次结构

标签 java oop

我正在为 REST 服务设计异常类层次结构,并面临以下问题。 请注意,该解决方案必须与 Java 7 兼容。

假设我正在构建一个管理考试的系统。假设我有以下资源:

  • 学生(学生 ID、名字、姓氏……)
  • 类(class)(类(class) ID、名称、...)
  • 考试(考试 ID、成绩、...)

以及以下操作(除其他外):

  • 获取/students/{studentId}
  • GET/courses/{courseId}
  • POST/students/{studentId}/exams(正文包含成绩和 courseId)

请注意,对于某些操作,courseId 作为 URL 的一部分提供,而对于其他操作,作为请求正文的一部分提供。

我想设计一个异常类层次结构,以一致的方式向客户端报告错误。我希望每个异常类都具有以下属性:

  • statusCode - 响应的 HTTP 状态代码,
  • errorCode - 错误的唯一标识符,
  • errorMessage - 人类可读的错误描述。

现在让我们关注类似“无效 ID”的错误。我有以下要求:

  • 如果作为 URL 的一部分提供了无效 ID,则 statusCode 应为 404(未找到)。如果它作为请求正文的一部分提供,那么它应该是 400(错误请求)。

  • errorCode/errorMessage 应从业务角度标识错误。 errorCode 应该是一个能够唯一标识错误原因的数字(假设 1 表示 invalid-studentId,2 表示 invalid-courseId 等),并且 errorMessage 应该以人类可阅读的格式描述原因(例如“ID 为学生” [135] 不存在。")

问题是,如何将这两个正交层次结构组合成一个异常类层次结构?

理想情况下,我会有以下异常类:

public abstract class ApiException extends Exception {

    public abstract int getStatusCode();
    public abstract int getErrorCode();
    public abstract String getErrorMessage();
}

public abstract class NotFoundException extends ApiException {

    public int getStatusCode() {
        return 404;
    }
}

public abstract class BadRequestException extends ApiException {

    public int getStatusCode() {
        return 400;
    }
}

public abstract class InvalidCourseIdException extends ApiException {

    private final String courseId;

    public InvalidCourseIdException(final String courseId) {
        this.courseId = courseId;
    }

    public int getErrorCode() {
        return 2;
    }

    public String getErrorMessage() {
        return "Course with ID [" + courseId + "] does not exist.";
    }
}

public class CourseNotFoundException extends NotFoundException, InvalidCourseException {
    public CourseNotFoundException(String courseId) {
        super(courseId);
    }
}

public class BadCourseException extends BadRequestException, InvalidCourseException {

    public BadCourseException(String courseId) {
        super(courseId);
    }
}

...

当然,Java 中不支持多重继承。如何设计一个兼容 Java 7 的类层次结构,遵循 DRY 原则(我想将每个常量值仅定义在一个位置)?

最佳答案

检查异常的关键在于您可以捕获它们并从状态中恢复。

异常不应按名称传输原因。如果出现 400 或 404,则无法恢复,因此应用程序应记录状态并中断。

ApiException 类已经足够开始了。

如果您害怕生成太多代码克隆。您可以创建一个 util 类来收集所有案例。

final class ApiThrowables {

       static final int BAD_REQUEST = 400; 
       static final int NOT_FOUND   = 404;

       public static ApiException newCourseIdNotFound(String courseId) {
          return new ApiException(2, NOT_FOUND,"Course with ID [" + courseId + "] does not exist.");
       }

       public static ApiException newBadCourseId(String courseId) {
          return new ApiException(2, BAD_REQUEST,"Course ID [" + courseId + "] is not valid.");
       }

    }

稍后,当您开发应用程序时,您可能会更改异常的设计,此组合将允许您这样做。当您使用继承而不是组合时,您的代码就变成了中继事物对,这抑制了更改和重用的潜力。

关于java - REST 服务的异常层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25688796/

相关文章:

java - 生成了错误的 SOAP 请求

java - 在 Java 中格式化日期

java - 添加 Maven 依赖项时会发生什么?

python - 类变量和实例变量的区别

php - 何时在 php OOP 中分离函数

c# - 遍历控件并使用函数

java - Java中的静态字符串路径

java - 执行 shell 命令时永远挂起 (Java)

python - 我应该如何在 Python 中声明实例变量的默认值?

java - 处理多部分/表单数据输入