我在我的应用程序中使用 Spark Framework,并使用
staticFileLocation("/META-INF/resources/");
这样我就可以使用 webjar,其中包含 css 和 js 文件。我还将自己的资源放入项目 src/main/resources/META-INF/resources
文件夹中,因为我的 gradle 构建会从那里获取它们。
我的构建使用 fat-jar 方法,所有内容最终都在一个 jar 中,并且所有文件都由 Spark 完美提供服务。
我的问题是,当我从 Eclipse 独立运行一些单元测试时,即使我确保 webjar 位于类路径上,它们也不会由 Spark 提供服务,只有我自己的项目静态资源提供服务。
@Test
public void testStartup() throws InterruptedException {
InputStream schemaIS = this.getClass().getClassLoader().getResourceAsStream("META-INF/resources/webjars/bootstrap/3.2.0/js/bootstrap.min.js");
System.out.println(schemaIS == null);
staticFileLocation("/META-INF/resources/");
// depending on the trailing / the bootstrap js is found, but Spark never serves it
}
我认为这与类加载器有关,但我没有找到使其工作的方法。查看 Spark 代码,它显示 线程上下文类加载器将用于加载资源。
我还看到代码本身删除了尾部斜杠,这在普通的 getResourceAsStream 中产生了很大的差异
.
这是 Spark 中的一个错误吗?或者有什么方法可以使其正常工作吗?
最佳答案
请注意 jetty 需要删除前导斜杠,而不是 Spark。
不幸的是,对于 Spark,您无法将静态文件(在物理目录/文件夹中)与作为 jar 中的资源的文件混合。许多 jar 包在 Spark 中也无法工作。
我几周前看过这个,并得出结论,这是 Spark 的一个小弱点(或者如果你可以说是一个错误)。
我发现的唯一方法是逆向 Spark 并弄清楚 jetty 是如何工作的。我使用以下 Nashorn javascript 片段来使 webjar 和静态文件协同工作。
除非 Spark 作者更改他的代码以允许包含定制的上下文处理程序,否则这对您没有帮助。但如果你想在jetty中进行操作,这段经过适配的代码可以帮助你。
此代码适用于 Nashorn jjs(来自 JDK8),但可以轻松移植到 Java。通过此代码,我可以使用 3 个独立的 webjar jquery/bootstrap/angular,其余的客户端代码位于物理目录/文件夹 public
中。
app.js:
with(new JavaImporter(
org.eclipse.jetty.server
, org.eclipse.jetty.server.handler
)) {
var server = new Server(4567);
var ctxs = new ContextHandlerCollection();
ctxs.setHandlers(Java.to([
load('src/static.js')
, load('src/webjars.js')
], Handler.class.getName().concat('[]')));
server.setHandler(ctxs);
server.start();
server.join();
}
src/static.js:
(function () {
var context;
with(new JavaImporter(
org.eclipse.jetty.server.handler
, org.eclipse.jetty.util.resource
)) {
context = new ContextHandler();
context.setContextPath("/");
var handler = new ResourceHandler();
handler.setBaseResource(Resource.newResource("public"));
context.setHandler(handler);
}
return context;
})();
src/webjars.js:
(function () {
var context;
with(new JavaImporter(
org.eclipse.jetty.server.handler
, org.eclipse.jetty.util.resource
)) {
context = new ContextHandler();
context.setContextPath("/");
var handler = new (Java.extend(ResourceHandler, {
getResource: function(req) {
var path = req.getUri();
var resource = Resource.newClassPathResource(path);
if (resource == null || !resource.exists()) {
resource = Resource.newClassPathResource("META-INF/resources/webjars" + path);
}
return resource;
}
}))();
handler.setDirectoriesListed(true); // true when debugging, false in production
context.setHandler(handler);
}
return context;
})();
关于java - Spark 无法从 webjar 加载静态文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30969091/