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

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

Мой основной класс - MainVerticle.java (Вертикаль):

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());
    }

}

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

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

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

Patrick 18.03.2019 18:50

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

user3243499 18.03.2019 18:59
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
970
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Теперь проблема исправлена. Проблема заключалась в том, что я не реализовал обработчик тела для полученного запроса в методе 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!");
    }

Вы можете упростить, определив однажды 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!");
   }

}

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");  
});

Другие вопросы по теме