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

时间:2019-06-21 15:09:00

标签: jar jetty 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

但都不起作用。

我在做什么错了?

1 个答案:

答案 0 :(得分:1)

您拥有的代码...

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

不适用于我,因为您不能使用类加载器来获取目录引用,而只能使用文件引用。呼叫ClassLoader.getResource("res")始终返回null。

此问题必须首先解决。

接下来,您对泽西岛的声明非常贪婪。

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

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

基于url模式的Servlet不可能“不处理”静态请求,而让Jetty服务那些静态请求。

放宽此网址格式,例如说/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);