无法使用嵌入式 Jetty 访问 JAR 文件中的静态资源

Unable to access static resources in JAR file using embedded Jetty

我的问题和这个问题基本一样:

Setting Jetty resourcebase to static file embedded in the same jar file

我正在使用嵌入式 Jetty,我想访问同一个 JAR 文件中的一些静态 HTML 文件。

Jetty 服务器的设置方式如下:


    ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
    context.setContextPath("/");
    String res = ApiServer.class.getClassLoader().getResource("res").toExternalForm();
    context.setResourceBase(res);

    jettyServer = new Server(port);
    jettyServer.setHandler(context);

    ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
    jerseyServlet.setInitOrder(0);

    // Tells the Jersey Servlet which REST service/class to load.
    String classes = new StringJoiner(",")
            .add(MyClass1.class.getCanonicalName())
            .add(MyClass2.class.getCanonicalName())
            .toString();

    jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, classes);

JAR 的文件夹结构是这样的:

root
  |  src (Java classes in here)
  |  res
      |  index.html

然而,它就是行不通。我尝试以各种方式访问​​ URL:

http://localhost:12345/res/index.html

http://localhost:12345/index.html

但都不起作用。

我做错了什么?

您拥有的代码...

String res = ApiServer.class.getClassLoader().getResource("res").toExternalForm();
context.setResourceBase(res);

对我不起作用,因为您不能使用类加载器获取目录引用,只能获取文件引用。调用 ClassLoader.getResource("res") 总是 returns null。

这需要先解决。

接下来,你的泽西岛申报太贪心了。

ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);

这意味着 Servlet (ServletContainer.class) 正在处理 100% 的所有请求,甚至是对静态内容的请求。

根据您的 url-pattern,Servlet 不可能 "not handle" 静态请求并让 Jetty 为这些静态请求提供服务。

放松这个url-pattern,说/api/*然后你会更近一步。

您需要的最后一件事是 DefaultServlet(Servlet 规范中的组件,以及提供静态文件的 Jetty)。

所以您将得到以下代码...

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
URL url = ApiServer.class.getClassLoader().getResource("res/index.html");
if (url == null)
   throw new FileNotFoundException("Whoops, can't find static resources folder");
URI webroot = url.toURI().resolve("./");
context.setBaseResource(Resource.newResource(webroot));

ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/api/*");
jerseyServlet.setInitOrder(0);

// Tells the Jersey Servlet which REST service/class to load.
String classes = new StringJoiner(",")
        .add(MyClass1.class.getCanonicalName())
        .add(MyClass2.class.getCanonicalName())
        .toString();

jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, classes);

// always named "default", always last, always on url-pattern "/"
ServletHolder defaultServ = new ServletHolder("default", DefaultServlet.class);
defaultServ.setInitParameter("dirAllowed","true");
context.addServlet(defaultServ,"/");

jettyServer = new Server(port);
jettyServer.setHandler(context);