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
- хорошее место для статических ресурсов с упаковкой.