1

我有一个在 tomcat 7 下运行的 Web 应用程序,在其中一个类中,我试图读取 WEB-INF/lib 文件夹下的一个 jar 中的文件。

URL resourceURL = MyClass.class.getClassLoader().getResource("xml/xslt/master.xsl");
File xslfile = new File(resourceURL.getPath());
AssertUtil.assertTrue(xslfile.exists(),"xsl file not found");

MyClass 和 master.xsl 都位于同一个 jar 中,并且打包没有问题。但是上面的代码片段在断言语句中失败,因为xslfile.exists返回 false。URL 正确解析为 jar 中文件的位置,如下所示

file:/<MY_WEBAPP_LOCATION>/MyApp/WEB-INF/lib/MyComponent.jar!/xml/xslt/master.xsl

其中 MY_WEBAPP_LOCATION 对应于我的 tomcat 服务器 webapp 目录的绝对路径。

但是,如果我重写下面的代码以读取为输入流,它就可以正常工作。

InputStream xslFile = MyClass.class.getClassLoader().getResourceAsStream("xml/xslt/master.xsl");

谁能解释是什么阻止了从 jar 资源创建文件,而输入流创建工作得很好。tomcat 端是否需要任何其他权限设置才能读取 jar 中的文件?

编辑:再观察一下,如果文件放在 WEB-INF/classes 下,则使用上述代码创建文件可以正常工作。问题仅在于将它放在 WEB-INF/lib 下的 jar 中

4

3 回答 3

0

小心似乎 ClassLoader.getResource 不处理相对路径。看到这个

GetResourceAsStream 恰好采用相对于 ClassLoader 的路径(而不是类!!)。我认为你很幸运,这里也有同样的东西。

于 2013-01-28T09:46:05.573 回答
0

如果它是桌面应用程序 getResource() 将起作用但由于这是一个 Web 应用程序,因此需要从 Context 中提取资源,因此 getResoruceAsStream()

于 2013-01-28T09:49:59.353 回答
0

这不是权限问题,而是使用 java.io.File API - 特别是构造函数http://docs.oracle.com/javase/7/docs/api/java/io/File.html#File%28java .lang.String%29

当您使用构建 File 对象时

File xslfile = new File(resourceURL.getPath());

您正在使用需要“抽象路径名”的 java.io.File#File(String) 方法。什么是可接受/有效的路径名由 File 类的 javadoc 描述:http: //docs.oracle.com/javase/7/docs/api/java/io/File.html

您从 getPath() 方法获得的字符串值:

file:/<MY_WEBAPP_LOCATION>/MyApp/WEB-INF/lib/MyComponent.jar!/xml/xslt/master.xsl

根本不构成有效的“抽象路径名”——它是一个转换为 java.lang.String 的 URL(恕我直言,应该返回 URL 方案为“jar”而不是“file”)。因此调用

isExist() 

返回 false,因为您的磁盘上没有具有该名称的文件。另一方面,如果资源在 jar 之外(例如,在 WEB-INF/classes 目录下),resourceURL.getPath() 将返回一个表示有效抽象路径名的值,因为所讨论的资源确实是一个简单文件。

当您使用 java.lang.ClassLoader#getResourceAsStream(java.lang.String) 时,该方法将资源直接流出到 java.lang.InputStream 中,甚至可能在其实现中不使用 File 类。

于 2013-01-28T21:15:11.540 回答