Получение исключения нулевого указателя в простой реализации маршрутизатора vertx

#java #vert.x

#java #vert.x

Вопрос:

Я изучаю платформу Vert.x на Java. Я пытаюсь создать простой API, используя Router и Vert.x web . Ниже приведен мой код:

Мой основной класс — MainVerticle.java (Verticle):

 public class MainVerticle extends AbstractVerticle{

    final int VA_PORT = 7535;

    @Override
    public void start() throws Exception {

        // URL routers
        IController controller = new RequestController();

        Router router = Router.router(vertx);

        router.post("/vassist").handler(
                routingContext -> controller.opController(routingContext) 
        );

        vertx.createHttpServer().requestHandler(router::accept).listen(VA_PORT, asyncResult -> {

            if(asyncResult.succeeded()) {
                LOGGER.info("Verticle deployed successfully. Listening on port: "   VA_PORT);
            }
            else {
                LOGGER.error("Could not start a HTTP server", asyncResult.cause());
            }

        });
    }

    @Override
    public void stop() throws Exception {
    }

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();

        // Deploy main verticle
        vertx.deployVerticle(new MainVerticle());
    }

}
  

Интерфейс — IController.java :

 public interface IController {
    public void opController(RoutingContext routingContext);
}
  

RequestController.java реализация вышеупомянутого интерфейса:

 public class RequestController implements IController {

    @Override
    public void opController(RoutingContext routingContext) {
        JsonObject jso = routingContext.getBodyAsJson();
        System.out.println("Received json body as : "   jso.encodePrettily());
    }

}
  

Приведенный выше код успешно развертывает verticle и создает http-сервер, однако всякий раз, когда я отправляю HTTP POST с образцом json тела, я получаю исключение с нулевым указателем в System.out.println("Received json body as : " jso.encodePrettily()); of RequestController.java .

Является ли моя реализация HTTPServer неверной? Пожалуйста, обратите внимание, что я не хочу писать обработчик http-запроса как анонимную функцию внутри creatHttpServer() метода vertx .

Комментарии:

1. похоже, что .getBodyAsJson () не удается создать экземпляр jso, что приводит к тому, что он равен нулю, когда println пытается его распечатать. Не уверен на 100%, что является его причиной.

2. @Patrick исправлено. Спасибо за ваш вклад и за то, что нашли время просмотреть мой код.

Ответ №1:

Теперь проблема исправлена. Проблема заключалась в том, что я не внедрил bodyhandler для принятого запроса в методе opController. Правильная реализация заключается в следующем:

 public void opController(RoutingContext routingContext) {
        routingContext.request().bodyHandler(bodyHandler -> {
            JsonObject jso = bodyHandler.toJsonObject();
            System.out.println("Received json body as : "   jso.encodePrettily());
        });

        // Complete request
        routingContext.response().setStatusCode(200).end("Done!");
    }
  

Ответ №2:

Вы можете упростить, определив один раз BodyHandler и получив тело в виде буфера, строки, json или массива json, как показано ниже:

 public class HttpServer extends AbstractVerticle {

   @Override
   public void start(Future<Void> startFuture) {
      var router = Router.router(vertx);
      //notice here
      router.route().handler(BodyHandler.create());

      // a bonus :) 
      router.route().handler(LoggerHandler.create(LoggerFormat.DEFAULT));

      router.post("/api/books").handler(this::getAllBooks);

      vertx.createHttpServer()
            .requestHandler(router)
            .listen(config().getInteger("server.port", 9000), lh -> startFuture.complete());
   }


   private void getAllBooks(RoutingContext rc) {
      // do something with the body
      JsonObject jso = rc.getBodyAsJson(); // or String body = getBodyAsString();
      System.out.println("Received json body as : "   jso.encodePrettily());
      //respond
      rc.response().setStatusCode(HttpResponseStatus.OK.code()).end("Done!");
   }

}
  

Ответ №3:

Vertx HTTPServer будет фиксировать все исключения, которые происходят в обработчиках маршрутизации, затем вернет http-ответ с кодом состояния = 500 (= «Внутренняя ошибка сервера»). Таким образом, http-сервер не будет остановлен никаким исключением.

используйте «try catch» для захвата исключений, например:

 String abc = null;
try {
    // add your code here
    abc.charAt(0);  
} catch (Exception e) {
    e.printStackTrace();
}
  

другой способ обработки исключений:

 router.route("/*").failureHandler(rc->{
    int statusCode = rc.statusCode();
    System.out.println("status code = "   statusCode );
    
    rc.response().setStatusCode(statusCode).end("failureHandler here");  
});