Vertx-web: где я могу разместить папку webroot?

Это должно быть легко, но это не так. Я немного работал с vert.x 2 и переключился на vert.x 3 в последнее время. Я думал, что попробую простой пример vertx-web, но не могу пройти простую подачу статических файлов.

Мой класс сервера содержит следующие фрагменты:

    HttpServer server = vertx.createHttpServer();
    Router router = ...;
    router.route("/static/*").handler(StaticHandler.create().setCachingEnabled(false));
    server.requestHandler(router::accept).listen(ctx.port);

Я использую Eclipse, но также пытаюсь запустить vertx из командной строки. Я также использую Maven. У меня есть три папки webroot, а vert.x не может найти ни одного из них:

myproject/webroot
myproject/src/main/resources/webroot
myproject/src/main/java/webroot

Каждый из этих "вебротов" содержит файл index.html и css/base.css.

Первый в моей корневой папке проекта. Второй - в папке ресурсов Maven, а третья - на моем classpath. В моей конфигурации запуска Eclipse я добавил myproject/src/main/resources/webroot в путь к классам, и я убедился, что мой рабочий каталог установлен в "myproject". При запуске из командной строки я попадал в каталог myproject, а мой script выглядит так:

JAVA_OPTS="-Dmyproject.port=8099" CLASSPATH="src/main/java:src/main/resources:target/dependencies/*:target/classes" vertx run com.my.MyProject

Независимо от того, я всегда получаю 404s, когда я пытаюсь использовать любой из этих URL-адресов:

http://localhost:8099
http://localhost:8099/
http://localhost:8099/index.html
http://localhost:8099/static/css/base.css

Что-нибудь еще мне нужно делать?

Ответ 1

Решение, которое я нашел, зависит от ответа на вопросы: где статический контент будет находиться во время выполнения и откуда вы хотите, чтобы vertx служил ему?

В моем случае установленная файловая система будет содержать статический контент (не в файле jar), и я хотел, чтобы vertx служил ему из этого местоположения, чтобы он мог быть обновлен в реальном времени. Таким образом, я отключил путь класса path в StaticHandler, установив свойство системы JVM vertx.disableFileCPResolving на true при запуске vertx.

Затем я поместил папку webroot в каталог, из которого запускается jvm. В моем случае я использую скрипты, гарантирующие, что jvm cwd всегда <app-root>/bin, поэтому достаточно удалить содержимое в <app-root>/bin/webroot. Если вы не можете гарантировать, где будет запущен jvm, это может быть более жестким, поскольку вам может потребоваться передать абсолютный путь StaticHandler.webroot(), указывающий на это фиксированное местоположение, но я думаю, что есть открытая проблема относительно поддержки этого (см. здесь).

Если статический контент будет упакован в банку, это немного проще. Вы можете добавить "webroot" в качестве ресурса в банке и разместить там весь контент, представляющий интерес. В этом случае вы не хотите отключать решение класса, поэтому либо установите vertx.disableFileCPResolving на false, либо не установите его вообще. Теперь, когда вы запустите vertx, он найдет webroot в файле jar и извлечет его содержимое в <cwd>/.vertx/.file-cache-<guid> (где cwd находится там, где вы начали jvm), и обслуживайте содержимое оттуда. Обратите внимание, что это небезопасно, если вы намерены делать живые обновления для контента, потому что любые изменения в файлах в этом каталоге будут потеряны, когда vertx выключится, потому что vertx-web удалит этот каталог. При перезагрузке он снова загрузит исходные файлы из ресурса jar, и изменения будут потеряны.

В любом случае, надеюсь, что это поможет.

Ответ 2

Выполните следующий код в любой точке останова, и он скажет вам корневой каталог, из которого он разрешит ваш запрос ресурса:

new File("").getCanonicalPath()

Запрос: localhost: 8080/static/ script.js

Handler:

router.route("/static/*").handler(StaticHandler.create("webroot"));

Файл должен находиться в MODULE_ROOT/webroot/script.js

Отладить весь путь в методе StaticHandlerImpl#sendStatic, чтобы увидеть, как ваши файлы будут разрешены, и использовать окно выражения для отладки, чтобы опросить файловую систему.

Ответ 3

Для меня работала настройка класса по умолчанию. Я использовал следующую иерархию:

Сохраните статический файл в каталоге main/resources/webroot

<AppRoot>/src/main/resources/webroot/static/index.html

И инициализируйте vertx следующим образом:

import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServer;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.StaticHandler;

Vertx vertx = Vertx.vertx();

Router router = Router.router(vertx);
router.route().handler(StaticHandler.create());

vertx.createHttpServer().requestHandler(router::accept).listen(8080);

Теперь вы можете получить к нему доступ по этому URL-адресу: http://localhost:8080/static/

Подробнее см. документацию vertx-web.

Ответ 4

Хорошо, я отвечу на свой вопрос. Во-первых, я должен указать, что я отключал части статического содержимого документов vertx-web (http://vertx.io/docs/vertx-web/js/#_serving_static_resources):

Любые запросы к путям, обрабатываемые статическим обработчиком, приведут к файлы, которые обслуживаются из каталога в файловой системе или из CLASSPATH. Статический каталог файлов по умолчанию - webroot, но это может.

В следующем примере все запросы к путям, начинающимся с /static/ будет обслуживаться из каталога webroot:

var StaticHandler = require("vertx-web-js/static_handler");

router.route("/static/*").handler(StaticHandler.create().handle);

и

Любые запросы к корневому пути/вызовут страницу индекса служил. По умолчанию индексной страницей является index.html. Это может быть настроен с помощью setIndexPage.

Мне казалось, что если я явно не определил обработчик для "/", то index.html будет неявно обслуживаться. И также казалось, что просто создание StaticHandler и добавление его к маршрутизатору будет достаточным для ресурсов CSS/JS/IMG. Я думаю, что мои предположения были неправильными.

Итак, я добавил следующее, что, по-видимому, необходимо:

во-первых, я сказал StaticHandler явно искать папку "webroot":

router.route("/static/*").handler(StaticHandler.create("webroot").setCachingEnabled(false));

то я явно добавил маршрут к моему маршрутизатору для обработки запросов к "/":

router.route("/").handler(ctx -> {
        Logger.log("Got an HTTP request to /");
        ctx.response().sendFile("webroot/index.html").end();
});

Ответ 5

Статические файлы, хранящиеся в /src/main/resources/assets/

ex: index.html

Router router = Router.router(vertx);
router.route("/files/*").handler(StaticHandler.create("assets"));
vertx.createHttpServer().requestHandler(router::accept).listen(8080);

Теперь вы можете получить к нему доступ из http://localhost:8080/files/index.html

Если вы посмотрите router.route("/files/*").handler(StaticHandler.create("assets"));

Когда запрос соответствует /files/, он вызывает StaticHandler, который указывает папку assets как web-root

Ответ 6

это решение работало для меня, чтобы добавить более подробную информацию, вот структура папки для меня

src
    main
        java
            com
                -- java files with vertx
        resources
            webroot
                html
                js

Ответ 7

Каталог

<AppRoot>/webroot/index.html

VertX

router.route("/app/*").handler(StaticHandler.create("webroot").setCachingEnabled(false));

URL

http://127.0.0.1/app/index.html

Добавьте следующие параметры виртуальной машины Java, чтобы включить горячую перезагрузку

-Dvertx.disableFileCPResolving=true

Ответ 8

Я считаю, что люди сталкиваются с примерами в документации для обслуживания статических ресурсов в http://vertx.io/docs/vertx-web/kotlin/#_serving_static_resources - некоторые из ответов даже зайдите так далеко, чтобы изменить маршрут маршрута, который не является желательным!

Я добавил https://github.com/vert-x3/issues/issues/265 с подробностями.

Среди прочего, ОП пытался:

http://localhost:8099/static/css/base.css

Это должно было сработать, остальные пути были недействительными, а src/main/resources/webroot - хорошее место для статических ресурсов с упаковкой.