多项目 gradle 构建中的 Jetty ResourceHandler 在错误的目录中查找

Jetty ResourceHandler in multi project gradle build looks in the wrong directory

我有一个使用 Gradle 的多项目构建,格式为:

project1
--build.gradle
--settings.gradle
project2
--src
----main
------java
--------LocalJettyRunner.java
------webapp
--------static
----------index.html

当我 运行 我的 LocalJettyRunner 并加载 localhost:8135 我得到一个 404 当我期待我的 ResourceHandler 到 return 我的 Index.html.我已经调试了 ResourceHandler.handle(...) 方法,它似乎在我的 project1/static 目录中查找,但显然不存在。我做错了什么?


LocalJettyRunner

public class LocalJettyRunner {}

    public void start() throws Exception {
        log.info("Starting api");

        ResourceHandler webHandler = new ResourceHandler();
        webHandler.setDirectoriesListed(true);
        webHandler.setResourceBase("static/");
        webHandler.setWelcomeFiles(new String[]{"index.html"});

        HandlerCollection handlers = new HandlerCollection();
        handlers.addHandler(webHandler);

        Server server = new Server(8135);
        server.setHandler(handlers);
        server.start();
    }

    public static void main(String[] args) throws Exception {
        new LocalJettyRunner().start();
    }
}

ResourceBase 设置为 "../project2/src/main/webapp/static" 似乎可以修复它,尽管我不确定为什么处理程序首先要查找 project1

ResourceBase 是绝对路径 and/or URL 到绝对路径。

它在没有绝对路径的情况下工作的事实是因为 new File(String).toAbsolutePath() 的工作方式。

尝试通过 ClassPath 在 ResourceBase 中查找您知道的资源,然后使用 URL 引用设置绝对路径。

示例:

假设你有一个src/main/resources/webroot/,里面有你的静态内容(比如index.html),那么你可以先解析它,再传入基础资源。

package jetty.resource;

import java.net.URI;
import java.net.URL;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.util.resource.Resource;

public class ResourceHandlerExample
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);

        // Figure out what path to serve content from
        ClassLoader cl = ResourceHandlerExample.class.getClassLoader();
        // We look for a file, as ClassLoader.getResource() is not
        // designed to look for directories (we resolve the directory later)
        URL f = cl.getResource("webroot/index.html");
        if (f == null)
        {
            throw new RuntimeException("Unable to find resource directory");
        }

        // Resolve file to directory
        URI webRootUri = f.toURI().resolve("./").normalize();
        System.err.println("WebRoot is " + webRootUri);

        ResourceHandler handler = new ResourceHandler();
        handler.setBaseResource(Resource.newResource(webRootUri));

        server.setHandler(handler);

        server.start();
        server.join();
    }
}

顺便说一下,您有一个 src/main/webapp/,它往往表示 Maven 的正确 webapp / war 文件。对于一个完整的网络应用程序,跳过 ResourceHandler 并直接使用 WebAppContext 可能更容易(它将所有内容连接起来,并且 不使用 ResourceHandler,而是 DefaultServlet,这更适合提供静态文件)