如何从打包在war文件中的jar文件中加载资源? [复制]

Posted

技术标签:

【中文标题】如何从打包在war文件中的jar文件中加载资源? [复制]【英文标题】:How to load resource from jar file packaged in a war file? [duplicate] 【发布时间】: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 中的资源?

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

【问题讨论】:

【参考方案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 我建议阅读 ***.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 中的一个类。

【讨论】:

以上是关于如何从打包在war文件中的jar文件中加载资源? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何从我的 jar 文件中访问资源文件夹中的文件夹?

请问maven工程jar包,war包,pom打包,都是怎么定的?

当存在 2 个版本的库时按需在 tomcat 中加载类?

从 jar 中加载图像以用于 Swing HTML

如何从资源位图文件中加载图像数据以进行 directshow 过滤器?

关于使用maven打包如何聚合资源文件