servlet 如何获取 servlet 外部文件的绝对路径?
Posted
技术标签:
【中文标题】servlet 如何获取 servlet 外部文件的绝对路径?【英文标题】:How a servlet can get the absolute path to a file outside of the servlet? 【发布时间】:2010-10-08 04:39:28 【问题描述】:我们一直在使用 System.getProperties("user.dir") 来获取属性文件的位置。现在它已部署在 Tomcat(通过 servlet)上,系统调用将位置作为 Tomcat,而不是属性文件所在的位置。
我们如何动态调用属性文件?
鉴于:
Tomcat 不是应用程序的唯一方式 将部署 我们无法控制应用的位置 可以放置。 相对路径不会那样工作 正在使用 Vista,而 Vista 中断 相对路径。 这必须适用于所有操作系统, 包括(但不限于)Linux, XP 和 Vista。 编辑我暗示了这一点,但如果我不够清楚,我没有办法 知道路径字符串。【问题讨论】:
我不认为相对路径是一个很好的解决方案(它的相对路径最终会在很大程度上取决于应用服务器)。但是从什么时候开始“Vista 打破了相对路径”?这没有任何意义。 我同意它没有,但经过几个月的相对路径传递给我,并且没有一个有效,我必须得出结论,Vista 在某处破坏了路径。我不是系统管理员,当我询问系统管理员时,我得到了他们的空白。 这就是我使用 System.getProperties("user.dir") 的原因,它会在 Vista、XP 和 Linux 上返回正确的路径。但不是 tomcat。 【参考方案1】:看看ServletContext
的getResource和getResourceAsStream方法。
【讨论】:
我希望有一种方法可以在普通类文件中获取 ServletContext。 感谢您的及时回复,但 getResource 方法需要路径字符串。我无法预测将要使用的路径。 @R.Bemrose,我一直在想办法破解这个问题。 要求文件在servlet“外部”,因此它不在类路径中。【参考方案2】:您可以将您的属性文件放在您的类路径中,并使用以下方式将它们作为输入流读取:
ClassName.class.getResourceAsStream(filePath + fileName);
其中 filePath 是从类路径根开始的文件的相对路径,fileName 是文件的名称。
如果您需要获取作为资源读取的文件的绝对路径,您可以执行以下操作:
ClassName.class.getResource(filePath + fileName).getPath()
【讨论】:
@neesh,如果你不知道文件路径,你是如何在 getResource() 调用中使用它的?我确信我只是误解了你在说什么。 假设您不知道 filePath 并且您想知道您的 web 应用程序部署目录的绝对路径。你可以这样做:ClassName.class.getResource("/").getPath(); 不适用于 Vista。否则会是一个很好的解决方案。 +1 真的吗? ..getResource("/").getPath() 在 Windows Vista 中返回什么? exception### 我必须再次运行它才能记住异常。我稍后会这样做并发布回复。现在没时间了【参考方案3】:是否可以将配置文件放在类路径中并通过 springs ClassPathResource 之类的方式引用它?
你应该可以这样使用它:
ClassPathResource foo = new ClassPathResource("file.name");
file.name 存在于类路径中最低级别的某个位置,例如:
/webapps/WEB-INF/classes/ 您的一个 jar 文件的基础【讨论】:
Spring 不是一个选项,在这种情况下,除了 java(servlet 是 java API 的一部分)之外,它必须与所有内容无关。不过,谢谢您的回复。 听起来你的处境很艰难。【参考方案4】:我认为ClassName.class.getResourceAsStream() 对你有用。该方法上的 cmets 指向 ClassLoader.getResource(),它告诉您如何在类路径中指定文件。
这样的事情应该可以工作:
InputStream foo = ClassName.class.getResourceAsStream("file.name");
file.name 位于类路径的某个位置。如果 file.name 在 com.foo.bar 包中,您将使用“/com/foo/bar/file.name”
【讨论】:
除了 Vista 之外的任何东西。 Vista打破了它。但这是迄今为止最接近的人。 +1 哦!很烂的男人如果我有 vista,我会进行测试,看看是否能找到答案。祝你好运。【参考方案5】:另一种方法可能是使用 -D 参数将变量值传递给 JVM。这样,您可以将代码绑定到相同的变量名称,然后在启动时传递不同的值。我还没有尝试过,但我认为它也应该适用于部署在 Tomcat 中的应用程序,如果您修改 startCatalina 脚本以将 -D 参数传递给 JVM
【讨论】:
【参考方案6】:您必须知道属性文件的路径,然后您可以将其包装在 File 中并传递给属性对象的 load() 方法。
如果您在 Tomcat 服务中运行,则您不是以安装它的用户身份运行的,因此您无法派生主目录。那么你很可能需要硬编码一些东西。
编辑:属性文件是相对于应用程序的。有关如何获取给定类的字节码的文件名的示例,请参阅http://www.exampledepot.com/egs/java.lang/ClassOrigin.html。您应该可以从那里继续。
Class cls = this.getClass();
ProtectionDomain pDomain = cls.getProtectionDomain();
CodeSource cSource = pDomain.getCodeSource();
URL loc = cSource.getLocation(); // file:/c:/almanac14/examples/
您应该知道,一些安全管理员不允许这样做。
【讨论】:
在Vista上工作,传递给Tomcat上测试。谢谢+1 我从未从 tomcat 方面得到答复,到目前为止,我正在接受您的回答,因为它实际上适用于 Vista。它只会让我害怕 Windows 7 会发生什么。可能还有另一篇文章。谢谢。【参考方案7】:您可以将属性文件的位置存储在 JNDI 中吗?
这应该可以跨 Tomcat 移植,并且适用于 Java EE 应用服务器。
【讨论】:
【参考方案8】:如果我正确理解了这个问题,另一种选择可能是在应用程序中的 jsp 或静态文件上调用 ServletContext.getRealPath()
并从结果中派生路径。
这意味着 webapp 部署为“扩展” - 即不是作为压缩的 war 文件 - 但这是大多数应用服务器所做的。
【讨论】:
这是最早的修复尝试之一。不能全面发挥作用。它转到 Tomcat 文件,而不是源文件。【参考方案9】:我们有同样的要求。到目前为止,最简单的方法是将 basedir 属性存储在我们已经加载的属性文件之一中。然后定义一个类似 getExternalDocPath(String path) 的方法。
这允许我们扩展 Tomcat 的文档库(只有 Tomcat 7 支持?)。在网上有人发布了一个类,它实际上扩展了 Tomcat 的文档库以允许多个路径,即“alpha;baker;charlie”。
【讨论】:
以上是关于servlet 如何获取 servlet 外部文件的绝对路径?的主要内容,如果未能解决你的问题,请参考以下文章
springBoot + IDEA配置外部Servlet容器