这应该是一个简单的,但它还没有到目前为止.我一直在努力工作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);
Run Code Online (Sandbox Code Playgroud)
我正在使用Eclipse,但也尝试vertx从命令行运行.我也在使用Maven.我有三个webroot文件夹,并且vert.x找不到它们:
myproject/webroot
myproject/src/main/resources/webroot
myproject/src/main/java/webroot
Run Code Online (Sandbox Code Playgroud)
每个'webroot'都包含一个index.html和一个css/base.css文件.
第一个是在我项目的根文件夹中.第二个是在Maven资源文件夹中,第三个应该是我的classpath.在我的Eclipse运行配置中,我将myproject/src/main/resources/webroot添加到类路径中,并确保我的工作目录设置为'myproject'.从命令行运行时,我在myproject目录中,我的脚本如下所示:
JAVA_OPTS="-Dmyproject.port=8099" CLASSPATH="src/main/java:src/main/resources:target/dependencies/*:target/classes" vertx run com.my.MyProject
Run Code Online (Sandbox Code Playgroud)
无论如何,当我尝试这些URL时,我总是得到404:
http://localhost:8099
http://localhost:8099/
http://localhost:8099/index.html
http://localhost:8099/static/css/base.css
Run Code Online (Sandbox Code Playgroud)
还有什么我需要做的吗?
我找到的解决方案取决于问题的答案:静态内容将在运行时在哪里,以及您希望vertx在哪里提供服务?
在我的情况下,安装的文件系统将是静态内容所在的位置(不是在jar文件中),我希望vertx从该位置提供服务,以便可以实时更新.因此,我通过将JVM系统属性vertx.disableFileCPResolving设置true为vertx启动来禁用StaticHandler中的类路径解析.
然后我将webroot文件夹放在启动jvm的目录下.在我的情况下,我使用的脚本保证jvm cwd始终是<app-root>/bin,所以删除内容<app-root>/bin/webroot就足够了.如果你不能保证jvm从哪里开始,它可能会更难,因为你可能需要传递一个指向这个固定位置的StaticHandler.webroot()的绝对路径,但我认为有一个未解决的问题关于对此的支持(见这里).
如果将静态内容打包到jar中,它会更简单一点.您可以在jar中添加"webroot"作为资源,并将所有感兴趣的内容放在那里.在这种情况下,您不希望禁用类路径解析,因此要么设置vertx.disableFileCPResolving为false,要么根本不设置它.现在,当你运行时vertx,它将webroot在jar文件中找到并将其内容提取到<cwd>/.vertx/.file-cache-<guid>(cwd无论你从哪里开始jvm),并从那里提供内容.请注意,如果您打算能够对内容进行实时更新,则这是不可行的,因为当vertx关闭时,该目录下的文件的任何更改都将丢失,因为vertx-web将删除该目录.重新启动时,它将再次从jar资源中检索原始文件,并且更改将丢失.
无论如何,希望这会有所帮助.
在任何断点处执行以下代码,它将告诉您将从中解析资源请求的根目录:
new File("").getCanonicalPath()
Run Code Online (Sandbox Code Playgroud)
请求:localhost:8080/static/script.js
处理器:
router.route("/static/*").handler(StaticHandler.create("webroot"));
Run Code Online (Sandbox Code Playgroud)
该文件应该在 MODULE_ROOT/webroot/script.js
一直调试到StaticHandlerImpl#sendStatic方法中以查看文件的解析方式,并使用调试表达式窗口来查询文件系统.
默认的classpath设置对我有用。我使用以下层次结构:
将静态文件保存在main/resources/webroot目录中
<AppRoot>/src/main/resources/webroot/static/index.html
Run Code Online (Sandbox Code Playgroud)
并如下初始化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);
Run Code Online (Sandbox Code Playgroud)
现在,您可以从以下URL访问它: http://localhost:8080/static/
有关更多信息,请参考vertx-web文档。
好吧,我会回答我自己的问题。首先,我应该指出,我关闭了 vertx-web 文档的静态内容部分(http://vertx.io/docs/vertx-web/js/#_serving_static_resources):
对静态处理程序处理的路径的任何请求都将导致从文件系统上的目录或类路径提供文件。默认静态文件目录是 webroot,但可以配置。
在以下示例中,对以 /static/ 开头的路径的所有请求都将从目录 webroot 获得服务:
var StaticHandler = require("vertx-web-js/static_handler");
router.route("/static/*").handler(StaticHandler.create().handle);
Run Code Online (Sandbox Code Playgroud)
和
对根路径 / 的任何请求都将导致提供索引页。默认情况下,索引页是index.html。这可以使用 setIndexPage 进行配置。
在我看来,如果我没有明确定义“/”的处理程序,那么将隐式地提供index.html。而且似乎只需创建一个 StaticHandler 并将其添加到路由器就足以满足 CSS/JS/IMG 资源的需要。我认为我的假设是不正确的。
所以我添加了以下内容,这似乎是所需要的:
首先,我明确告诉 StaticHandler 寻找“webroot”文件夹:
router.route("/static/*").handler(StaticHandler.create("webroot").setCachingEnabled(false));
Run Code Online (Sandbox Code Playgroud)
然后,我明确地向路由器添加了一条路由来处理对“/”的请求:
router.route("/").handler(ctx -> {
Logger.log("Got an HTTP request to /");
ctx.response().sendFile("webroot/index.html").end();
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11651 次 |
| 最近记录: |