我在我的应用程序中使用Spark Framework,并使用
staticFileLocation("/META-INF/resources/");
这样我就可以使用webjars,其中包含css和js文件。我也有自己的资源放在我的项目src/main/resources/META-INF/resources
文件夹中,因为我的gradle构建从那里获取它们。
我的构建使用了一种胖jar方法,其中所有内容都以一个jar形式结束,所有文件都由Spark完美提供。
我的问题是,当我从Eclipse独立运行一些单元测试时,即使我确保webjars在classpath上,它们也不是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代码,它说The thread context class loader will be used for loading the resource.
我也看到代码本身删除了尾部斜杠,这在普通getResourceAsStream
中有很大的不同。
它是Spark中的错误,还是有任何方法可以使其正常工作?
答案 0 :(得分:1)
注意 删除前导斜杠是Jetty所必需的,而不是Spark。
不幸的是,Spark不能将静态文件(在物理目录/文件夹中)与作为jar资源的文件混合使用。许多罐子在Spark中都不起作用。
我几周前看过这个并得出结论,这是Spark中的一个小弱点(或者你可能会说错误)。
我发现的唯一方法是反转Spark并弄清楚码头是如何工作的。我使用以下Nashorn javascript片段进行管理,以使webjars和静态文件协同工作。
除非Spark作者更改其代码以允许包含定制的上下文处理程序,否则这对您无济于事。但是如果你想在码头上寻找,那么这个改编的代码可以帮助你。
此代码适用于Nashorn jjs(来自JDK8),但可以轻松移植到Java。使用此代码,我能够使用3个单独的webjars 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;
})();