【问题标题】:Setting Jetty resourcebase to static file embedded in the same jar file将Jetty资源库设置为嵌入在同一个jar文件中的静态文件
【发布时间】:2021-03-18 06:10:54
【问题描述】:

我正在尝试访问打包在同一个 .jar 文件 (testJetty.jar) 中的静态资源 (例如 first.html),该文件还有一个启动码头 (v.8) 服务器 (MainTest.java) 的类.我无法正确设置资源库。

我的jar文件(testJetty.jar)的结构: testJetty.jar

  • first.html

  • MainTest.java

== 在本地机器上工作正常,但是当我将它包装在 jar 文件中然后运行它时,它不起作用,出现“404:找不到文件”错误。

我尝试使用以下值设置资源库,但均失败:

a) 尝试将其设置为 .

resource_handler.setResourceBase("."); // Results in directory containing the jar file, D:\Work\eclipseworkspace\testJettyResult

b) 尝试从 getResource 获取它

ClassLoader loader = this.getClass().getClassLoader();
File indexLoc = new File(loader.getResource("first.html").getFile());
String htmlLoc = indexLoc.getAbsolutePath();
resource_handler.setResourceBase(htmloc); // Results in D:\Work\eclipseworkspace\testJettyResult\file:\D:\Work\eclipseworkspace\testJettyResult\testJetty1.jar!\first.html

c) 尝试获取 webdir

String webDir = this.getClass().getProtectionDomain()
        .getCodeSource().getLocation().toExternalForm();
resource_handler.setResourceBase(webdir); // Results in D:/Work/eclipseworkspace/testJettyResult/testJetty1.jar

这 3 种方法都不起作用。

任何帮助或替代方法将不胜感激

谢谢 阿巴斯

【问题讨论】:

    标签: jar jetty embedded-jetty


    【解决方案1】:

    此线程中提供的解决方案有效,但我认为解决方案的一些明确性可能有用。

    如果您正在构建一个胖 jar 并使用 ProtectionDomain 方式,您可能会遇到一些问题,因为您正在加载整个 jar!

    class.getProtectionDomain().getCodeSource().getLocation().toExternalForm();
    

    所以更好的解决方案是其他提供的解决方案

    contextHandler.setResourceBase(
      YourClass.class
        .getClassLoader()
        .getResource("WEB-INF")
        .toExternalForm());
    

    这里的问题是,如果你正在构建一个胖 jar,你并没有真正将你的 webapp 资源转储到 WEB-INF 中,而是可能进入了 jar 的根目录,所以一个简单的解决方法是创建一个文件夹 XXX 并使用第二种方法如下:

    contextHandler.setResourceBase(
      YourClass.class
        .getClassLoader()
        .getResource("XXX")
        .toExternalForm());
    

    或者更改您的构建工具以将 webapp 文件导出到该给定目录。也许 Maven 会为您在 Jar 上执行此操作,但 gradle 不会。

    【讨论】:

      【解决方案2】:

      并不罕见,我找到了解决问题的方法。 Stephen 在Embedded Jetty : how to use a .war that is included in the .jar from which Jetty starts? 中提到的第三种方法奏效了!

      所以,我从 Resource_handler 更改为 WebAppContext,其中 WebAppContext 指向同一个 jar (testJetty.jar) 并且它起作用了!

          String webDir = MainTest.class.getProtectionDomain()
                  .getCodeSource().getLocation().toExternalForm(); ; // Results in D:/Work/eclipseworkspace/testJettyResult/testJetty.jar
          WebAppContext webappContext = new WebAppContext(webDir, "/");
      

      【讨论】:

        【解决方案3】:

        看起来 ClassLoader.getResource 不理解空字符串或 .或 / 作为参数。在我的 jar 文件中,我必须将所有 stuf 移动到 WEB-INF(任何其他包装目录都可以)。所以代码看起来像

        contextHandler.setResourceBase(EmbeddedJetty.class.getClassLoader().getResource("WEB-INF").toExternalForm()); 所以上下文看起来像这样:

        ContextHandler:744 - 已启动 o.e.j.w.WebAppContext@48b3806{/,jar:file:/Users/xxx/projects/dropbox/ui/target/ui-1.0-SNAPSHOT.jar!/WEB-INF,AVAILABLE}

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-09
          • 1970-01-01
          • 2020-03-11
          • 2012-05-04
          • 2013-05-23
          • 2016-11-04
          相关资源
          最近更新 更多