Tomcat 7 使用新 URL 和“类路径”字符串获取资源,ClassLoader.getSystemClassLoader().getResource 返回 null

Posted

技术标签:

【中文标题】Tomcat 7 使用新 URL 和“类路径”字符串获取资源,ClassLoader.getSystemClassLoader().getResource 返回 null【英文标题】:Tomcat 7 get resource using new URL and "classpath" string , ClassLoader.getSystemClassLoader().getResource return null 【发布时间】:2021-11-11 07:11:47 【问题描述】:

我尝试使用此代码在 tomcat 7 中获取文件资源:

confFileUrl = new URL("classpath:/conf/plugins/my_app_conf.txt");
        final URL resourceUrl = ClassLoader.getSystemClassLoader().getResource(confFileUrl.getPath());
        URLConnection urlc =  resourceUrl.openConnection();

WEB-INF 如下所示:

WEB-INF/classes/conf/plugins/my_app_conf.txt

我需要加载它并验证它是否存在并将其作为 URL 对象传递给第三方应用程序(仅接受 URL 对象)

但问题是:

ClassLoader.getSystemClassLoader().getResource(confFileUrl.getPath());

结果总是 null

知道为什么吗?

【问题讨论】:

【参考方案1】:

注意:您在问题中混合了文件名:gappFileUrl vs confFileUrl。

当您专门检查 SystemClassLoader 时,您不会获得您的 webapp 的类加载器,因此找不到任何东西。

使用this.getClass().getResourceAsStream(name) 来利用webapp 的类加载器(或者,更准确地说,加载当前类的类加载器。希望它也来自WEB-INF/libWEB-INF/classes。如果不是,请选择一个可以在那里找到的类。

还请注意,Web 应用程序不一定要“分解”(解压缩)到文件系统中,但可以从 WAR 文件合法地提供服务。因此,您需要使用流操作,并且不能期望任何基于文件的操作能够始终如一地工作。

编辑(在您发表评论后):我从未在 URL 中使用过 classpath: 组件。来自https://docs.oracle.com/javase/8/docs/technotes/guides/lang/resources.html(强调我的):

getResource() 方法返回资源的 URL。 URL(及其表示)特定于实现和 JVM(即,在一个运行时实例中获得的 URL 可能在另一个运行时实例中不起作用)。它的协议通常特定于加载资源的 ClassLoader。 如果资源不存在或出于安全考虑不可见,则方法返回 null。

如果客户端代码想要以 InputStream 的形式读取资源的内容,它可以在 URL 上应用 openStream() 方法。这很常见,足以证明将 getResourceAsStream() 添加到 Class 和 ClassLoader 是合理的。 getResourceAsStream() 与调用 getResource().openStream() 相同,只是 getResourceAsStream() 捕获 IO 异常返回 null InputStream。

...

getResource 和 getResourceAsStream 方法查找具有给定名称的资源。如果找不到具有指定名称的资源,则返回 null。搜索与给定类关联的资源的规则由该类的 ClassLoader 实现。在应用命名约定后,Class 方法委托给 ClassLoader 方法:如果资源名称以“/”开头,则按原样使用。否则,在将所有句点 (.) 转换为斜杠 (/) 之后,会附加包的名称。

基于此:尝试加载名为 "/conf/plugins/my_app_conf.txt" 的资源。而且您不需要通过 URL 构造,但您可以将该名称正确传递给 getResourceAsStream,例如...getResourceAsStream("/conf/plugins/my_app_conf.txt");

【讨论】:

感谢 allot ,但更改为 :this.getClass().getResource(confFileUrl.getPath()); 后仍然返回 null我的班级在:WEB-INF\classes\com\example\my_tomcat_demo\HelloServlet.class

以上是关于Tomcat 7 使用新 URL 和“类路径”字符串获取资源,ClassLoader.getSystemClassLoader().getResource 返回 null的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat 7/JBoss7 的自定义会话 ID 生成器

tomcat 7 7.0.73 url 参数 大括号 {} 不支持 , 7.0.67支持

如何将文件夹添加到由 maven cargo 插件启动的 Tomcat 容器的类路径中

尝试从GWT-RPC项目获取的Tomcat 7上的部署战争

在我的类路径中获取 tomcat-jdbc.jar 的推荐方法是啥?

使用启用了安全管理器的 Tomcat 时,在类路径中找不到属性文件