servletcontext.getRealPath("/") 是啥意思,我应该啥时候使用它

Posted

技术标签:

【中文标题】servletcontext.getRealPath("/") 是啥意思,我应该啥时候使用它【英文标题】:What does servletcontext.getRealPath("/") mean and when should I use itservletcontext.getRealPath("/") 是什么意思,我应该什么时候使用它 【发布时间】:2012-08-23 01:01:07 【问题描述】:

在下面的sn-p中:

ServletContext context = request.getServletContext();
String path = context.getRealPath("/");

getRealPath()方法中的/代表什么?我应该什么时候使用它?

【问题讨论】:

称为WebApplicationContext。例如您有名为 TestWebApp 的应用程序,然后 / 将提供路径直到 TestWebApp 它是您的网络应用程序的根。 【参考方案1】:

简介

ServletContext#getRealPath() 旨在将 Web 内容路径(服务器磁盘文件系统上扩展的 WAR 文件夹结构中的路径)转换为绝对磁盘文件系统路径。

"/" 代表 Web 内容根。 IE。它代表web 文件夹,如下面的项目结构:

YourWebProject
 |-- src
 |    :
 |
 |-- web
 |    |-- META-INF
 |    |    `-- MANIFEST.MF
 |    |-- WEB-INF
 |    |    `-- web.xml
 |    |-- index.jsp
 |    `-- login.jsp
 :    

因此,将"/" 传递给getRealPath() 将返回项目扩展WAR 文件的/web 文件夹的绝对磁盘文件系统路径。 /path/to/server/work/folder/some.war/ 之类的东西,您应该可以在 FileFileInputStream 中进一步使用。

请注意,大多数初学者似乎没有看到/意识到您实际上可以将整个 Web 内容路径传递给它并且他们经常使用

String absolutePathToIndexJSP = servletContext.getRealPath("/") + "index.jsp"; // Wrong!

甚至

String absolutePathToIndexJSP = servletContext.getRealPath("") + "index.jsp"; // Wronger!

而不是

String absolutePathToIndexJSP = servletContext.getRealPath("/index.jsp"); // Right!

永远不要在那里写文件

另外请注意,即使您可以使用FileOutputStream 将新文件写入其中,但只要重新部署 WAR,所有更改(例如新文件或编辑的文件)都将丢失;原因很简单,所有这些更改都不包含在原始 WAR 文件中。所以所有试图在其中保存上传文件的初学者都做错了。

此外,getRealPath() 将始终返回 null 或当服务器未配置为将 WAR 文件扩展为磁盘文件系统时,会返回一个完全意外的路径,而是进入例如内存作为虚拟文件系统。

getRealPath() 不可携带;你最好不要使用它

谨慎使用getRealPath()。实际上 没有 明智的现实世界用例。根据我 20 年的 Java EE 经验,总是有另一种方式比 getRealPath() 更好、更便携。

如果您真正需要的是获取 Web 资源的 InputStream,最好使用 ServletContext#getResourceAsStream(),无论 WAR 的扩展方式如何,这都将起作用。因此,例如,如果您想要 index.jsp 中的 InputStream,那么 not 这样做:

InputStream input = new FileInputStream(servletContext.getRealPath("/index.jsp")); // Wrong!

而是这样做:

InputStream input = servletContext.getResourceAsStream("/index.jsp"); // Right!

或者,如果您打算获取所有可用网络资源路径的列表,请改用ServletContext#getResourcePaths()

Set<String> resourcePaths = servletContext.getResourcePaths("/");

您可以通过ServletContext#getResource() 获取URL 的单个资源。当资源不存在时,这将返回null

URL resource = servletContext.getResource(path);

或者,如果您打算保存上传的文件或创建临时文件,请参阅下面的“另请参阅”链接。

另见:

getResourceAsStream() vs FileInputStream Recommended way to save uploaded files in a servlet application Simple ways to keep data on redeployment of Java EE 7 web application

【讨论】:

我 100% 确定 @BalusC 会回答这个问题,而且答案非常棒。说真的,你太棒了。 @BalusC 这会给ServletConfig#getServletContext().getRealPath(".")带来什么? @BalusC 如果我的输入和输出文件在 WEB-INF 中,我如何使用 getResourceAsStream 或 getResourcePaths 来引用它们? @te7:只需使用getResourceAsStream("/WEB-INF/filename.ext")getResourcePaths("/WEB-INF")。关键是指定一个以/开头的webcontent-relative路径。 @BalusC 信息:getResourcePaths 在一个字符串变量中返回 /WEB-INF 中每个文件的所有路径...据我所知不可用。供参考。我还没有尝试过使用 getResourceAsStream ,因为这需要对我的 2 个工作班中的所有方法进行大修。我在一种方法上进行了尝试,但编译器似乎无法为其解析 servletContext,因为上下文超出了该方法的范围。我想我必须将 servletContext 从它包含的 doPost 方法传递给它。如果我能正常工作,我会发回。【参考方案2】:

我的方法:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException 

    try 
        String path = request.getRealPath("/WEB-INF/conf.properties");
        Properties p = new Properties();
        p.load(new FileInputStream(path));

        String StringConexion=p.getProperty("StringConexion");
        String User=p.getProperty("User");
        String Password=p.getProperty("Password");
    
    catch(Exception e)
        String msg = "Excepcion " + e;
    

【讨论】:

虽然这段代码 sn-p 可以解决问题,但它没有解释为什么或如何回答这个问题。请include an explanation for your code,因为这确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。【参考方案3】:

Java 7 和 Java 8 之间也有一个变化。诚然,它涉及一个已弃用的调用,但我必须添加一个“/”才能让我们的程序正常工作!这是讨论它的链接Why does servletContext.getRealPath returns null on tomcat 8?

【讨论】:

【参考方案4】:

Web 应用程序的上下文路径是包含 Web 应用程序的 WEB-INF 目录的目录。它可以被认为是网络应用程序的“家”。通常,在编写 Web 应用程序时,获取此目录在文件系统中的实际位置可能很重要,因为这允许您执行诸如读取文件或写入文件之类的操作。

这个位置可以通过 ServletContext 对象的 getRealPath() 方法获得。此方法可以传递一个字符串参数集到 File.separator 以使用操作系统的文件分隔符(UNIX 为“/”,Windows 为“\”)获取路径。

【讨论】:

以上是关于servletcontext.getRealPath("/") 是啥意思,我应该啥时候使用它的主要内容,如果未能解决你的问题,请参考以下文章