【问题标题】:How to load resource from jar file packaged in a war file? [duplicate]如何从打包在war文件中的jar文件中加载资源? [复制]
【发布时间】:2011-06-02 21:38:48
【问题描述】:

我需要从 jar 中加载一个属性文件。 jar 包含在 war 文件中。这是结构

ROOT.war
  WEB-INF
     lib
       my.jar

here my.jar has following structure

my.jar
  com
    test
      myservlet.class
  WEB-INF
    test.property

现在我在我的一个 servlet 中编写了以下代码,如下所示:

InputStream stream = getServletContext().getResourceAsStream("/WEB-INF/test.properties");
Properties prop = new Properties();
prop.load(stream );

但在上面的代码中,我将流设为空。如果我将属性文件放在 ROOT.war/WEB-INF 它工作正常。我很清楚,如果 getResourceAsStream 中的路径以“/”开头,而不是在上下文根中搜索资源。但是如何读取位于根应用程序的 WEB-INF/lib 中的 jar 中的资源?

感谢和问候, 阿米特·帕特尔

【问题讨论】:

    标签: java servlets


    【解决方案1】:

    将它放在 JAR 的根目录中,并通过上下文类加载器而不是 servletcontext 获取它。

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    InputStream input = classLoader.getResourceAsStream("test.properties");
    // ...
    

    /WEB-INF 文件夹约定特定于 WAR 文件,而不是 JAR 文件。摆脱它。如果您确实需要一个单独的 JAR 文件夹作为类路径的一部分,请改用 /META-INF

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    InputStream input = classLoader.getResourceAsStream("META-INF/test.properties");
    // ...
    

    【讨论】:

    • ...或保持原样并使用“WEB-INF/test.property”。
    • @bkail,也可以,但是没有理由使用 WEB-INF 文件夹,因为 servletcontext 永远无法访问该文件夹。将特定于 WAR 的文件夹约定放在普通的 JAR 文件中也是没有意义的。
    • 同意,并不意味着您的答案不正确。只需为 OP 提供另一种选择,以防由于某种原因难以或无法更改 JAR 结构。
    • 另一个有趣的点是 getFile 有时(在 WildFly 的情况下)返回不正确的路径,因此您必须使用 getResourceAsStream
    • 我建议阅读 stackoverflow.com/a/2161583/2412477,因为它更详细地介绍了这个问题。这是问题的最佳答案,这篇文章是[重复]的。然而,这个问题的措辞更适合我的特定问题,所以我就是这样来到这里的 =)
    【解决方案2】:

    您可以从给定实例访问标准类路径上的任何资源

    this.getClass().getResourceAsStream("name");
    

    例如来自您的“myservlet”类(错误命名)。

    getServletContext().getResourceAsStream() 访问 Web 应用程序基目录上下文中的内容。

    在 jar 中包含 WEB-INF 目录似乎很糟糕——你会引起混乱。找不到更好的名字吗?

    【讨论】:

      【解决方案3】:

      这是我发现的,它对我有用。 @BalusC 提供的帮助对我有用。我已经整理了我发现的内容以及我如何验证它是否有效。

      我有一个如下结构的maven项目

      现在当我构建这个项目时;罐子看起来像

      这里 queries.properties 移动到“META-INF”文件夹下。现在,如果这个 jar 有一个类试图使用这个属性文件 Thread.currentThread().getContextClassLoader().getResourceAsStream("queries.properties")

      认为在项目结构中显示的资源文件夹下仍然可以访问相同的文件,这是错误的。正确的方法是通过 META-INF 文件夹访问

      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
      InputStream is = classLoader.getResourceAsStream("META-INF/queries.properties");
      

      我是如何验证的

      只需创建一个简单的 java 项目并将刚刚创建的 jar 包含到它的构建路径中,然后创建一个具有上述 ClassLoader 语句的类实例。您在这个新的 java 项目中的代码应该看起来像

      public static void main(String[] args){
              new Queries();
          }
      

      Queries 是您刚刚包含在构建路径中的 jar 中的一个类。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-17
        • 2010-11-17
        • 2015-11-16
        • 2010-11-13
        • 2010-11-25
        • 2012-05-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多