【问题标题】:How a servlet can get the absolute path to a file outside of the servlet?servlet 如何获取 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。

标签: java tomcat servlets filepath os-agnostic


【解决方案1】:

看看ServletContextgetResourcegetResourceAsStream方法。

【讨论】:

  • 我希望有一种方法可以在普通类文件中获取 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”。

      【讨论】:

        猜你喜欢
        • 2014-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-22
        • 2017-09-01
        • 1970-01-01
        • 2016-09-13
        相关资源
        最近更新 更多