【问题标题】:REST validation handling in Vert.xVert.x 中的 REST 验证处理
【发布时间】:2019-11-16 18:01:52
【问题描述】:

我正在关注官方文档中的example,但我无法弄清楚错误处理的工作原理。

如果我从路由处理程序中执行routingContext.fail(400),它将进入无限循环。如果我不这样做,则不会调用路由器处理程序。

路由处理程序

HTTPRequestValidationHandler validationHandler = HTTPRequestValidationHandler.create().addPathParam("id", ParameterType.UUID);
router.get("/api/job/:id")
    .handler(validationHandler)
    .handler(jobController::getJob)
    .failureHandler((routingContext) -> {
        Throwable failure = routingContext.failure();
        if (failure instanceof ValidationException) {
            // Something went wrong during validation!
            String validationErrorMessage = failure.getMessage();
            //routingContext.fail(400);
          }
        });

路由器处理程序

router.errorHandler(400, routingContext -> {
      if (routingContext.failure() instanceof ValidationException) {
        final JsonObject error = new JsonObject()
          .put("timestamp", System.nanoTime())
          .put("error", routingContext.failure().getMessage())
          .put("exception", routingContext.failure().getStackTrace().toString());
        routingContext.response().setStatusCode(400).end(error.encode());

      } else {
        // Unknown 400 failure happened
        routingContext.response().setStatusCode(400).end();
      }
    });

【问题讨论】:

    标签: java vert.x


    【解决方案1】:

    routingContext.fail() 再次导致上下文失败,因此它会导致无限循环始终执行/api/job/:id 的特定失败处理程序。如果要执行下一个故障处理程序(本例中为路由器的 400 错误处理程序),必须调用routingContext.next()

    如果您需要对端点 /api/job/:id 进行特定的错误处理,请使用特定的故障处理程序并编写响应。 如果您不需要任何特定的错误处理并且只想对错误 400 使用通用错误处理,请使用 router.errorHandler() 而不向端点添加任何特定的故障处理程序

    【讨论】:

      【解决方案2】:

      根据router.errorHandler()实现

      当上下文失败并且其他失败处理程序没有写入回复或在处理程序内引发异常时,将调用处理程序。 因此,如果我们希望在特定的路由错误处理中捕获错误,但仍将其交给路由器错误处理程序,我们需要从路由处理程序中抛出运行时异常。

      路由处理程序

      HTTPRequestValidationHandler validationHandler = HTTPRequestValidationHandler.create().addPathParam("id", ParameterType.UUID);
      router.get("/api/job/:id")
          .handler(validationHandler)
          .handler(jobController::getJob)
          .failureHandler((routingContext) -> {
              Throwable failure = routingContext.failure();
              if (failure instanceof ValidationException) {
                  throw new RuntimeException(failure.getMessage());
                }
              });
      

      还将 toe 错误代码修改为 500 以捕获所有错误并在路由器错误处理程序中包含错误类型逻辑。

      路由器处理程序

      router.errorHandler(500, routingContext -> {
            if (routingContext.failure() instanceof ValidationException) {
              final JsonObject error = new JsonObject()
                .put("timestamp", System.nanoTime())
                .put("error", routingContext.failure().getMessage())
                .put("exception", routingContext.failure().getStackTrace().toString());
              routingContext.response().setStatusCode(400).end(error.encode());
      
            } else {
              // Unknown 400 failure happened
              routingContext.response().setStatusCode(400).end();
            }
          });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-22
        • 2017-11-28
        • 1970-01-01
        • 2021-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-11
        相关资源
        最近更新 更多